esp-iot-solution bq27220 电量计驱动版本演进:电池档案校验、CONFIG UPDATE 流程加固与重启回归测试
物联网嵌入式驱动开发硬件开发【免费下载链接】esp-iot-solutionEspressif IoT Library. IoT Device Drivers, Documentations and Solutions.项目地址https://gitcode.com/GitHub_Trending/es/esp-iot-solution点击查看免费下载本文以 bq27220 组件的 CHANGELOG.md 为主线梳理该 BQ27220 单节锂电池电量计驱动从 v0.1.0 到 v0.1.2 的完整演进过程并结合 bq27220.c 的源码实现深入讲解 v0.1.2 中电池档案Gas Gauge Profile完整校验、Data Memory 带校验传输、CONFIG UPDATE 模式状态确认以及 ESP-IDF 6.x 测试应用兼容与 200 次重启回归测试的具体实现帮助读者理解“档案写一次、重启不再重写”这一关键行为是如何被验证和保障的。一、版本演进总览根据 CHANGELOG.md该组件共经历三个版本版本日期变更类型核心内容v0.1.22026-09-07Bug Fixes完整校验电池档案再决定是否跳过更新修复 DOD50 与单字节参数写入Data Memory 带校验传输、目标化写入与全量读回验证并传播错误确认 CONFIG UPDATE 转换与设备再初始化后恢复密封状态增加 ESP-IDF 6.x 测试应用兼容与手动重复重启回归测试v0.1.12025-09-22Bug Fix将依赖i2c_bus改为 public修复编译错误v0.1.02025-08-12Enhancements初始版本提供 BQ27220 电量计基础功能当前 idf_component.yml 中version: 0.1.2与 CHANGELOG 的最新条目一致说明仓库处于 v0.1.2 状态。BQ27220 是 TI 的单节锂电池电量计芯片采用 CEDVCompensated End-of-Discharge-Voltage补偿放电截止电压算法计量电量通过 I2C 与主机通信I2C 地址0x55见 bq27220.c 中的BQ27220_I2C_ADDRESS官方文档见 battery_fuel_gauge.rst 中的已适配列表。v0.1.0基础功能落地初始版本提供了电量计驱动的基础能力设备识别读取DeviceNumber寄存器并校验值是否为0x0220、Seal/Unseal 安全访问控制、电池参数写入与状态/电量查询。对外 API 集中在 bq27220.h涵盖生命周期管理bq27220_create()/bq27220_delete()安全控制bq27220_seal()/bq27220_unseal()以及 16 位参数读写bq27220_set_parameter_u16()/bq27220_get_parameter_u16()状态查询电压bq27220_get_voltage()、电流bq27220_get_current()、SOCbq27220_get_state_of_charge()、SoHbq27220_get_state_of_health()、温度bq27220_get_temperature()单位 0.1°K、剩余容量、充/放电时间预估、循环计数等。v0.1.1i2c_bus 依赖可见性修复该版本的修复点在 idf_component.yml 中可以直接看到dependencies: espressif/i2c_bus: version: ^1.4 public: true idf: 4.4 cmake_utilities: 0.*组件的公开头文件 bq27220.h 直接#include i2c_bus.h且bq27220_config_t结构体以i2c_bus_handle_t作为成员调用方必须能找到i2c_bus组件的头文件。在 ESP-IDF Component Manager 中依赖默认仅对组件自身可见private下游工程的编译无法解析该头文件从而产生编译错误。将i2c_bus声明为public: true后依赖会透传给所有使用该组件的工程这一声明即 v0.1.1 修复的落地形式。v0.1.2四项关键加固v0.1.2 是本轮演进的核心CHANGELOG 列出的四条 Bug Fixes 均围绕一个主题让电池档案的“校验—写入—验证—密封”流程可靠、可重复、可测试。下面逐条结合源码展开。1. 完整校验电池档案并修复 DOD50 与单字节参数写入驱动初始化时会把应用层传入的 parameter_cedv_t容量、EDV 阈值、EMF/C0/R0/T0/R1/TC 等 CEDV 系数、DOD0~DOD100 电压表与 gauging_config_tCCT、CSYNC、SC、FCC_LIM、IGNORE_SD 等计量配置位域展开为 26 个档案字段见 bq27220_get_profile_fields()。v0.1.2 修复的两处历史问题正隐藏在这份字段表与底层地址映射中DOD50 地址问题CEDV Profile 1 中 DOD 表的 Data Memory 地址在 bq27220_data_memory.c 中是连续映射的VOLTAGE_50_DOD位于0x92C7。此前若字段到地址的映射出现错位DOD50 会读写到错误位置导致 50% SOC 附近的电压—DOD 对应关系失真。单字节参数写入档案中存在单字节字段SELF_DISCHARGE_RATE以及TC与C1两个 8 位系数打包成一个 16 位寄存器0x92B1见 bq27220_get_profile_fields() 中PROFILE_FIELD(TC_C1, BQ_DM_TC, ((uint16_t)cedv-TC 8) | cedv-C1, 2)的拼接方式。字段表用size区分 1/2 字节字段读写时按实际大小处理bq27220_get_block_field()/bq27220_set_block_field()对size 1的字段只处理低字节修复后单字节参数不再被错误地按 16 位打包或截断。“完整校验”则体现在bq27220_create()的入口决策逻辑 bq27220.c先对全部非学习字段执行bq27220_verify_profile(handle, config, false)排除FullChargeCapacity这一学习值只有全部匹配才跳过更新并直接 seal任何一个字段不一致都会触发 CONFIG UPDATE 流程。2. Data Memory 带校验传输、目标化写入与全量读回验证Data Memory 的访问协议要求先写SELECT_SUBCLASS定位块地址传输数据再通过MAC_DATA_SUM携带校验和提交。v0.1.2 将这条链路全部改为 checked 风格并传播错误读块带地址回显确认bq27220_read_dm_block() 每次读取后解析前 2 字节回显地址与请求地址比对不匹配则重试最多BQ27220_DM_READY_POLL_COUNT20次超时返回ESP_ERR_TIMEOUT避免读到错误块的数据写块带校验和提交bq27220_write_dm_block() 按0xFF - sum计算整块校验和bq27220_get_checksum()提交后延时BQ27220_DM_ACCESS_DELAY_MS10 ms等待器件处理目标化写入targeted writes26 个字段不再逐地址零散下发而是先聚合到 8 个连续块s_profile_write_blocks[]如EMF起 12 字节、VOLTAGE_0_DOD起 22 字节 DOD 表再整块提交见 s_profile_write_blocks 与 bq27220_write_profile()日志会打印Battery profile written in 8 targeted blocks全量读回验证bq27220_verify_profile() 通过 3 个更大的只读块s_profile_read_blocks[]一次读回覆盖区逐字段比较任何不一致返回ESP_ERR_INVALID_STATE日志打印期望值与实际值Profile verify mismatch at ... expected... actual...错误传播底层寄存器读取拆出 checked 版本 bq27220_read_u16_checked()I2C 传输失败通过ESP_RETURN_ON_ERROR一路向上传播最终bq27220_create()在通信、更新或验证任一环节失败时返回NULL见 README.md 末段对初始化语义的说明。3. 确认 CONFIG UPDATE 转换与再初始化然后恢复密封配置参数只有在 CONFIG UPDATE 模式下才允许写入且退出后器件会重新初始化。v0.1.2 用轮询确认替代盲等完整流程见 bq27220_create()为Unseal连续写入UNSEALKEY1/UNSEALKEY2→ 进入FULLACCESSKEY双密钥全访问模式并读取OperationStatus确认SEC位为 FULLbq27220_enter_full_access()下发CONTROL_ENTER_CFG_UPDATE延时BQ27220_CFG_UPDATE_ENTER_DELAY_MS1100 msbq27220_wait_cfg_update(true) 以 20 ms 间隔、最多 100 次轮询OperationStatus的CFGUPDATE位确认确实进入CONFIG UPDATE 模式写入档案 立即全量读回验证此时包含学习容量字段include_learned_capacity true下发CONTROL_EXIT_CFG_UPDATE_REINIT静置BQ27220_CFG_UPDATE_EXIT_SETTLE_MS2000 ms后轮询确认CFGUPDATE清零即器件再初始化完成调用 bq27220_seal() 恢复密封状态若当前SEC非 SEALED 则下发CONTROL_SEALED等待 Kconfig 配置的密封稳定时间后复查状态位确认密封成功才返回ESP_OK。密封稳定时间由 Kconfig 开放配置CONFIG_BQ27220_SEAL_SETTLE_MS取值 0~10000 ms默认 2000 ms。若第 4 步写档案失败错误路径会走exit_cfg_update标签尽力下发CONTROL_EXIT_CFG_UPDATE避免器件停留在 CONFIG UPDATE 模式。4. ESP-IDF 6.x 测试应用兼容与手动重复重启回归测试v0.1.2 让测试应用同时兼容 ESP-IDF 4.4~6.x。test_apps/sdkconfig.defaults 中同时保留了两套 CPU 频率配置项CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_240对应 IDF 5.0CONFIG_ESP32S2_DEFAULT_CPU_FREQ_240/CONFIG_ESP32S3_DEFAULT_CPU_FREQ_240对应 IDF 4.4未知配置项会被各版本工具链忽略从而实现跨版本构建。更实质的是新增的手动回归测试用例bq27220 profile is not rewritten after 200 ESP restartsbq27220_test.c它针对“档案校验失败导致每次重启都重复重写档案”这一类回归缺陷设计了闭环验证用一个__NOINIT_ATTR状态结构magic 取反 magic 重启计数 所用档案跨esp_restart()保持进度magic 校验保证 RAM 残留数据不可信时重新起步首次运行用默认 CEDV 初始化并要求档案恰好更新一次若芯片里已是默认档案则临时改用DOD201的 alternate 档案人为制造一次不一致保证必有一次真实写入通过esp_log_set_vprintf()挂钩日志、统计驱动打印Start updating battery profile的次数来客观判定更新次数随后执行 200 次esp_restart()每次重启后重新初始化并断言更新次数为 0——即密封的档案在反复重启后始终命中“跳过更新”分支测试应用还内置 Unity 框架用例bq27220 basic information query test以及 setUp/tearDown 中的堆内存泄漏检查bq27220_test.c。二、组件使用方式与配套工具依赖与配置组件声明依赖espressif/i2c_bus ^1.4public、idf 4.4idf_component.yml构建规则见 CMakeLists.txt源文件bq27220.c、bq27220_data_memory.c私有头priv_include。唯一 Kconfig 选项为CONFIG_BQ27220_SEAL_SETTLE_MS默认 2000 ms。最小集成示例摘自 README.md 的用法与 bq27220.h 中结构体定义一一对应#define I2C_MASTER_SCL_IO GPIO_NUM_1 /*! gpio number for I2C master clock */ #define I2C_MASTER_SDA_IO GPIO_NUM_2 /*! gpio number for I2C master data */ // Default Gauging Parameter static const parameter_cedv_t default_cedv { .full_charge_cap 650, .design_cap 650, .reserve_cap 0, .near_full 200, .self_discharge_rate 20, /* 单字节字段自放电率索引%/day value × 0.0025 % */ .EDV0 3490, /* 0% SOC 截止电压 (mV) */ .EDV1 3511, /* 3% SOC 截止电压 (mV) */ .EDV2 3535, /* 低电量截止电压 (mV) */ .EMF 3670, /* 高于最高 EDV 的无载开路电压 (mV) */ .C0 115, /* 容量相关的 EDV 调整因子 */ .R0 968, /* 一阶速率因子内阻补偿 */ .T0 4547, /* 温度-内阻因子 */ .R1 4764, /* 容量-内阻因子 */ .TC 11, /* 低温内阻调整T 23°C与 C1 打包写入 0x92B1 */ .C1 0, /* EDV0 处期望保留容量 */ .DOD0 4147, /* 0% DOD 电压 */ .DOD10 4002, .DOD20 3969, .DOD30 3938, .DOD40 3880, .DOD50 3824, .DOD60 3794, .DOD70 3753, .DOD80 3677, .DOD90 3574, .DOD100 3490, /* 100% DOD放空电压 */ }; // Default Gauging Config static const gauging_config_t default_config { .CCT 1, .CSYNC 0, .EDV_CMP 0, .SC 1, .FIXED_EDV0 0, .FCC_LIM 1, .FC_FOR_VDQ 1, .IGNORE_SD 1, .SME0 0, }; i2c_config_t conf { .mode I2C_MODE_MASTER, .sda_io_num I2C_MASTER_SDA_IO, .sda_pullup_en GPIO_PULLUP_ENABLE, .scl_io_num I2C_MASTER_SCL_IO, .scl_pullup_en GPIO_PULLUP_ENABLE, .master.clk_speed 400 * 1000, }; i2c_bus_handle_t i2c_bus i2c_bus_create(I2C_NUM_0, conf); bq27220_config_t bq27220_cfg { .i2c_bus i2c_bus, .cfg default_config, .cedv default_cedv, }; bq27220_handle_t bq27220 bq27220_create(bq27220_cfg); /* 通信/更新/验证失败时返回 NULL */README 末尾同时说明了 v0.1.2 后的初始化语义驱动会校验档案全部非学习字段匹配则跳过 CONFIG UPDATE否则写入所需 Data Memory 区段、等待再初始化、验证完整档案并密封任一环节失败bq27220_create()返回NULL。配套采样工具 sample-data-app组件自带 tools/sample-data-app 辅助工具以 CSV 格式ElapsedTime, Voltage, Current, Temperature周期性打印采样数据默认截止放电电压 3.3 V可 menuconfig 修改采集结果可直接导入 TI 的 GPCCEDV 工具自动生成上述 CEDV 档案参数为parameter_cedv_t提供实测依据。其日志样例README也能看到 v0.1.2 的日志行为打印固件/硬件版本、档案关键字段后输出Skip battery profile update。三、小结v0.1.2 修复的工程意义从 CHANGELOG 的条目与源码实现看v0.1.2 解决的是一条“写入侧”可靠性问题链判断依据完整化——用 26 字段全量校验替代不完整检查修复 DOD50 地址映射与单字节字段自放电率、TC/C1 打包寄存器0x92B1的写入缺陷确保“匹配才跳过”的判定可信传输过程可验证——Data Memory 读回显地址确认、写校验和提交、I2C 错误逐级传播杜绝静默失败模式转换可确认——CFGUPDATE位轮询确认进入与退出 CONFIG UPDATE等待器件再初始化完成后立即恢复密封失败路径也有兜底退出回归可自动化——200 次软件重启的手动回归测试用例 IDF 4.4~6.x 兼容的测试应用让“重启不重写档案”这一行为可以被重复验证。测试应用完整代码可参考 bq27220_test.cCEDV 寄存器地址映射可参考 bq27220_data_memory.c驱动全部实现集中在 bq27220.c。赞分享物联网嵌入式驱动开发硬件开发【免费下载链接】esp-iot-solutionEspressif IoT Library. IoT Device Drivers, Documentations and Solutions.项目地址https://gitcode.com/GitHub_Trending/es/esp-iot-solution点击查看免费下载相关推荐ESP-IoT-Solution 电池电量计Battery Fuel Gauge组件详解MAX17048/MAX17049 与 BQ27220 驱动实战ESP IoT Solution 电池电量计Battery Fuel Gauge组件详解MAX17048/MAX17049 与 BQ27220 驱动实战物联网嵌入式驱动开发硬件开发esp-iot-solution 电池电量计Battery Fuel Gauge传感器驱动实战指南MAX17048 与 BQ27220 的 SOC/FCC 监测方案esp iot solution 电池电量计Battery Fuel Gauge传感器驱动实战指南MAX17048 与 BQ27220 的 SOC/FCC物联网嵌入式驱动开发硬件开发XLeRobot 组装指南660 美元 4 小时搭建双臂移动机器人XLeRobot 组装指南660 美元 4 小时搭建双臂移动机器人 XLeRobot 是基于 IKEA 工具车和双 SO101 机械臂的开源双臂移动家庭机器人具身智能智能硬件创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

SAP现金订单流程V2.0:从创建到清账的闭环实践

SAP现金订单流程V2.0:从创建到清账的闭环实践

简介:SAP现金订单业务处理流程V2.0是一份面向印度子公司录单文员及销售、仓库、财务人员的SAP实操手册,重点解决现金销售从订单创建、发货过账到开票清账的全链路效率与准确性问题。资源仅含1个PDF文档,压缩包约756KB,内容编排适合…

2026/10/14 17:11:36 阅读更多 →
PHM故障预测与健康管理落地实战:从状态监控到维护决策

PHM故障预测与健康管理落地实战:从状态监控到维护决策

简介:PHM故障预测与健康管理技术专题文档面向设备维护工程师、可靠性研究人员及智能制造从业者,系统梳理了从传统事后维护转向预测性维护的核心思路。文档围绕状态监测—故障预测—健康管理主线,详细介绍传感数据采集、机器学习分析、故障预测…

2026/10/14 17:10:35 阅读更多 →
FastapiAdmin RBAC权限管理实战:菜单、按钮、数据三级权限配置全流程教程

FastapiAdmin RBAC权限管理实战:菜单、按钮、数据三级权限配置全流程教程

后端前端认证鉴权代码生成移动开发 【免费下载链接】FastapiAdmin FastapiAdmin 是一套完全开源的快速开发平台,提供免费使用。它结合了现代、高性能的技术栈,后端采用Fastapi SQLAlchemy,前端采用基于 vue3 typescript vite pinia Elem…

2026/10/14 17:10:35 阅读更多 →

最新新闻

数据库与缓存实战指南:从MySQL索引到Redis穿透与雪崩

数据库与缓存实战指南:从MySQL索引到Redis穿透与雪崩

得,直接开始正题。聊到互联网后端,我估计前面两篇已经把HTTP协议、Web框架、接口设计这些基础盘得差不多了,这篇咱们必须得换个频道,聊聊在“学习记录”这个系列里最劝退、也最躲不开的硬骨头——数据库与缓存。你去看各大招聘网站…

2026/10/14 18:00:22 阅读更多 →
aiogram 入门实战:用完全异步的 Python 框架快速构建 Telegram Bot

aiogram 入门实战:用完全异步的 Python 框架快速构建 Telegram Bot

后端即时通讯API设计 【免费下载链接】aiogram aiogram is a modern and fully asynchronous framework for Telegram Bot API written in Python using asyncio 项目地址: https://gitcode.com/gh_mirrors/ai/aiogram 点击查看 免费下载 aiogram 是一个基于 Pytho…

2026/10/14 18:00:22 阅读更多 →
高项论文质量管理写作指南:从过程组到工具用法的落地拆解

高项论文质量管理写作指南:从过程组到工具用法的落地拆解

每年软考成绩出来之后,评论区里最热闹的往往是论文。尤其是“论项目的质量管理”这个题目,经常出现在备选列表里,也年年有大把考生栽在它上面。按理说,质量管理是项目管理者最不陌生的领域:开发要做测试、交付要有验收…

2026/10/14 18:00:22 阅读更多 →
HarmonyOS 6.0+分布式App开发实战:跨端协同与设备重组

HarmonyOS 6.0+分布式App开发实战:跨端协同与设备重组

1. 跨端开发不是在“移植”,是在“重组”做了几年的多端应用,我越来越觉得“跨端”这个词被理解得太浅了。很多人以为跨端就是把手机上的页面缩一缩放到平板上,或者把App打包成能够在不同系统上跑一遍的安装包。但实际上,真正的跨…

2026/10/14 18:00:22 阅读更多 →
IT培训行业技术管理者的职业发展路径解析

IT培训行业技术管理者的职业发展路径解析

1. 项目背景解析这个标题看似夸张,实则反映了一个职场人从基层逆袭到高管的成长故事。作为在黑马程序员广州校区工作多年的老员工,我亲眼见证过不少技术人通过自身努力实现职业跃迁的真实案例。今天我们就来拆解一个技术管理者从校区基层做到集团高管的典…

2026/10/14 18:00:22 阅读更多 →
C#与松下PLC通信:Mewtocol协议串口/以太网例程与避坑指南

C#与松下PLC通信:Mewtocol协议串口/以太网例程与避坑指南

简介:面向工业自动化上位机开发者的C#与松下PLC通信完整示例工程,以手机屏幕异物检测为应用场景,演示通过串口、TCP/IP等方式与PLC交互,完成数据采集与指令下发。资源包共113个文件,以C#源码(.cs)为主,另有…

2026/10/14 17:59:21 阅读更多 →

日新闻

AnyPS5通用适配层设计:兼容性与性能的工程取舍

AnyPS5通用适配层设计:兼容性与性能的工程取舍

1. 从"AnyPS5"这个名字说起:它到底想解决什么问题第一次看到"AnyPS5"这个标题,我脑子里冒出来的第一个念头是:这大概率是一个围绕"跨平台运行"或者"通用适配"做文章的项目。名字里的"Any"…

2026/10/14 0:00:41 阅读更多 →
Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

1. 项目概述:Flutter跨平台二手交易应用开发作为一名长期从事移动应用开发的工程师,我最近完成了一个基于Flutter框架的二手物品交易平台项目。这个项目最吸引我的地方在于它完美结合了Flutter的跨平台优势与HarmonyOS的生态特性,实现了"…

2026/10/14 0:00:41 阅读更多 →
DFS算法解决飞机降落调度问题实战

DFS算法解决飞机降落调度问题实战

1. 项目背景与核心思路飞机降落问题是一个经典的调度优化场景,也是算法竞赛和面试中的高频题目。这个题目要求我们合理安排多架飞机的降落顺序和时间,确保所有飞机都能安全着陆而不发生冲突。在实际航空管制中,这类问题直接关系到飞行安全和机…

2026/10/14 0:00:41 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/14 3:30:28 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/14 16:30:29 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/14 3:29:58 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 22:01:27 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 14:57:39 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/14 7:53:34 阅读更多 →