Linux thermal framework 温控框架:架构、配置与排查实战
1. 从一次散热异常说起thermal framework 到底在管什么去年调一块嵌入式板子的时候遇到个怪事设备跑压力测试CPU 频率被压到最低性能惨不忍睹但手摸散热片温度并不高。查了半天才发现是 thermal zone 里一个温度传感器的校准值写错了内核以为芯片已经 90 多度拼命触发降频。这个坑让我意识到thermal framework 这套东西平时不显山不露水一旦配置出问题表现出的症状往往和温度看起来毫无关系。Linux 内核功耗子系统里thermal framework 是专门负责温度管理的那一层。它干的事情说白了就三件读温度、判断是否越界、越界了就采取动作。听起来简单但内核要面对的是几十个传感器、多种降温手段、各种触发策略还要保证响应及时又不误伤性能所以这套框架被抽象成了几个核心概念thermal zone温区、thermal governor温控策略、cooling device降温设备、trip point触发点。这几个词后面会反复出现先把它们的关系理清楚后面看代码和配置就不会晕。这篇文章适合谁看如果你在做嵌入式 Linux 开发、功耗优化、或者单纯想搞明白/sys/class/thermal下面那一堆文件是干嘛的那这篇就是给你准备的。我会从整体架构讲到具体的数据结构和注册流程再结合实操把配置和排查方法过一遍。不需要你事先精通内核但至少得知道设备树是什么、驱动模型大概怎么回事不然有些地方会卡住。我个人的习惯是学一个内核子系统先看它的骨架——也就是核心数据结构和它们之间的引用关系然后再看血肉——具体的注册流程和回调。thermal framework 尤其适合这么学因为它的设计思路非常清晰就是围绕zone 管理设备、governor 决策、cooling device 执行这条主线展开的。2. thermal framework 的整体架构与设计思路2.1 为什么内核需要一套独立的温控框架早年间温控逻辑是散落在各个驱动里的CPU 驱动自己读温度自己降频GPU 驱动也来一套结果就是各管各的互相不知道对方在干嘛。CPU 觉得自己很热降了频其实 GPU 更热但没人管或者两个驱动同时抢着降频性能直接崩掉。这种碎片化的做法在单核时代还能凑合到了 SoC 上几十个发热单元的时代就彻底不行了。thermal framework 的核心价值就是统一收口。它把所有温度传感器抽象成 thermal zone把所有能降温的东西抽象成 cooling device中间用一个 governor 来做决策。这样一来温度信息的来源和执行动作的去向都被框架管起来了驱动只需要注册自己的传感器和降温能力剩下的调度交给框架。这个设计思路和很多内核子系统一样——把共性抽到框架层把差异留给驱动。另一个考量是策略与机制分离。降温的机制比如调 CPU 频率、开风扇、限制 GPU由 cooling device 提供而什么时候降、降多少这种策略由 governor 决定。这样换策略不用改驱动加新硬件也不用重写策略扩展性一下就上来了。内核里目前有几种 governor后面会细说。2.2 四个核心概念的关系梳理先把这四个概念用一张表对照清楚不然后面容易混概念职责典型代表对应 sysfsthermal zone代表一个温控区域绑定温度传感器CPU 温区、GPU 温区/sys/class/thermal/thermal_zoneXthermal governor决策策略决定如何降温step_wise、fair_share挂在 zone 上cooling device实际执行降温的硬件CPUfreq、风扇、GPU/sys/class/thermal/cooling_deviceXtrip point触发阈值温度到这就动作passive、active、criticalzone 下的 trip_point_X它们的关系可以这样理解一个 thermal zone 绑定一个温度传感器里面配置了若干 trip point。温度上升碰到某个 trip point 时zone 通知 governorgovernor 根据策略决定让哪些 cooling device 降档cooling device 执行后温度下降形成一个闭环。整个过程是事件驱动的不是轮询——温度变化触发中断或轮询定时器然后走一遍上面的流程。这里有个容易忽略的点一个 cooling device 可以被多个 zone 共享。比如 CPUfreq 这个 cooling device可能同时被 CPU 温区和主板温区引用。框架内部用引用计数管理这种共享关系避免一个 zone 释放了设备结果另一个 zone 还在用。这个设计在实际系统里很常见因为一个发热源往往影响多个温度监测点。2.3 与内核其他子系统的耦合点thermal framework 不是孤立的它和好几个子系统有交互。最直接的是CPUfreq因为降频是最常用的降温手段thermal 通过 cooling device 接口去调用 CPUfreq 的限频能力。其次是hwmon很多温度传感器本身是 hwmon 设备thermal 可以复用它们。还有device tree现代 ARM 平台上 thermal zone 和 trip point 基本都在设备树里描述驱动解析后注册。另外它和PM电源管理子系统也有交集尤其是系统级休眠时thermal 需要正确处理挂起和恢复避免恢复后状态错乱。我遇到过恢复后 governor 状态没重置导致降温不生效的情况后面排查章节会讲。理解这些耦合点很重要因为实际调试时问题往往出在交界处。比如温度读不到可能是 hwmon 驱动没起来降频不生效可能是 CPUfreq 的 cooling device 没注册成功。知道框架和谁打交道排查时就能顺着链路往下找。3. 核心数据结构与注册流程拆解3.1 thermal_zone_device温区的载体thermal_zone_device是整个框架的核心结构一个实例代表一个温区。它里面有几个关键字段值得单独拎出来说。type是温区的名字会出现在 sysfs 里比如 cpu-thermalops是一组回调框架通过它去读温度、获取趋势trips是 trip point 数组governor指向当前使用的策略cooling_devices是绑定的降温设备列表。读温度这件事框架本身不关心硬件怎么读它只调用ops-get_temp。这个回调由具体的传感器驱动实现返回的是毫摄氏度注意单位很多新手在这里栽跟头返回了摄氏度结果温度判断全错。趋势判断用ops-get_trend返回升温、降温还是稳定governor 会参考这个做更平滑的决策。注册一个 zone 用thermal_zone_device_register或者带参数的版本。注册时会做几件事分配 ID、创建 sysfs 节点、初始化 governor、绑定 cooling device。如果设备树里配了 trip point注册前要先解析好传进来。这里有个顺序问题——cooling device 必须先注册zone 才能绑定它否则绑定会失败。我见过有人把注册顺序写反结果降温设备死活不生效查了半天。3.2 thermal_cooling_device降温能力的抽象thermal_cooling_device代表一个能降温的设备。它的核心是ops里的几个回调get_max_state返回最大档位get_cur_state返回当前档位set_cur_state设置档位。档位是个非负整数0 通常表示不降温越大降温越猛。框架不关心档位具体对应什么硬件操作那是驱动的事。举个例子CPUfreq 作为 cooling device 时档位可能对应不同的频率限制。档位 0 是不限制档位 1 限制到某个频率档位越大限制越狠。驱动在set_cur_state里把档位翻译成具体的频率上限然后调用 CPUfreq 的接口去设置。这个翻译逻辑是驱动自己的事框架只负责告诉它该用第几档了。注册用thermal_cooling_device_register需要提供类型名和 ops。类型名很重要因为 zone 在设备树里是通过类型名或者 phandle 来引用 cooling device 的。类型名重复会导致注册失败所以命名要有区分度别都用 cpu。3.3 trip point 与 governor 的绑定机制trip point 是温区里的阈值点每个点有类型、温度和滞后值。类型主要有几种passive表示该降频了active表示该开风扇之类的主动散热critical表示危险必须关机hot介于 passive 和 critical 之间。滞后值hysteresis是为了防止温度在阈值附近抖动导致反复触发比如阈值 80 度、滞后 2 度那降到 78 度以下才认为解除。governor 和 trip point 是配合工作的。以step_wise为例温度碰到 passive trip 时它不会一次性把 cooling device 拉满而是逐步加档每次升一档观察温度是否回落这样避免过度降温影响性能。这个逐步的逻辑就是 step_wise 名字的由来。而fair_share则是把降温需求按比例分配给多个 cooling device适合有多个降温手段的场景。绑定过程是这样的zone 注册时指定 governor 名字框架找到对应的 governor 结构并调用它的bind。如果没指定用默认的。governor 在throttle回调里根据当前温度和 trip point 决定 cooling device 的档位。整个决策链路是温度更新 → 检查 trip → 调用 governor → governor 操作 cooling device。3.4 设备树里的 thermal 描述现代 ARM 平台基本都在设备树里描述 thermal。一个典型的 zone 节点包含传感器引用、polling 延迟、trip point 列表、cooling device 映射。trip point 用temperature和hysteresis描述cooling map 用trip和cooling-device把 trip 和降温设备关联起来还能指定影响的最小最大档位。这里有个细节polling-delay和polling-delay-passive是两个不同的值。前者是常规轮询间隔后者是进入被动降温后的轮询间隔通常更短因为这时候需要更快响应。如果传感器支持中断触发可以设polling-delay为 0 走中断模式但很多简单传感器还是靠轮询。解析设备树的代码在of-thermal.c里它把设备树节点翻译成thermal_zone_device需要的参数。如果设备树写错了比如引用了不存在的 cooling device注册会失败并打印错误。我建议设备树改完后先看 dmesgthermal 相关的报错通常比较明确能直接定位到哪个节点有问题。4. 实操从零配置一个温控区域4.1 确认硬件与传感器可用动手之前先确认硬件层面没问题。第一步是看系统里有没有温度传感器被识别出来。最直接的办法是ls /sys/class/thermal/如果里面有thermal_zoneX说明已经有 zone 注册了。再cat一下对应的temp文件看能不能读到合理数值。读出来是 0 或者明显离谱的值说明传感器驱动有问题先解决这个再谈温控。如果什么都没有那可能是传感器驱动没编译进内核或者没加载。用dmesg | grep -i thermal看有没有相关日志。有些平台的传感器挂在 hwmon 下可以先ls /sys/class/hwmon/确认传感器本身是否工作再考虑怎么把它接入 thermal 框架。我一般会先用 hwmon 确认硬件正常再去看 thermal 层。还有一点权限。读温度一般不需要特殊权限但改 trip point 或者 governor 需要 root。调试阶段直接用 root别在权限上浪费时间。4.2 通过 sysfs 手动验证温控逻辑在写设备树之前可以用 sysfs 手动验证一遍逻辑这样能快速确认框架工作正常。步骤大致是这样找到目标 zone比如/sys/class/thermal/thermal_zone0查看当前温度cat temp确认数值合理查看当前 governorcat policy确认策略查看 trip pointcat trip_point_0_temp和trip_point_0_type查看绑定的 cooling devicels cooling_device*如果想手动触发降温测试可以临时把某个 trip point 的温度改低比如echo 40000 trip_point_0_temp单位毫摄氏度即 40 度然后观察 cooling device 的cur_state是否变化。这个操作有风险温度阈值设太低可能导致设备频繁降频测试完记得改回去。我一般会在可控环境下做这个测试确认链路通了再写进设备树。注意直接改 trip point 温度是调试手段不要在生产环境用。改完不恢复重启后可能行为异常。4.3 设备树配置示例与参数计算设备树里配置 thermal 的典型结构长这样以某 ARM 平台为例具体节点名按实际平台调整thermal-zones { cpu_thermal: cpu-thermal { polling-delay-passive 100; polling-delay 1000; thermal-sensors cpu_sensor; trips { cpu_alert: cpu-alert { temperature 75000; hysteresis 2000; type passive; }; cpu_crit: cpu-crit { temperature 95000; hysteresis 2000; type critical; }; }; cooling-maps { map0 { trip cpu_alert; cooling-device cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT; }; }; }; };参数怎么定polling-delay常规 1000ms 够用被动降温时 100ms 响应更快。trip 温度要参考芯片手册passive 一般设在芯片能长期稳定工作的温度上限附近critical 设在绝对上限减一点余量。滞后值 20002 度是常见值太小会抖动太大响应迟钝。THERMAL_NO_LIMIT表示不限制档位范围也可以指定具体的最小最大档位来精细控制。4.4 验证配置生效的完整流程配置写完后重新编译设备树、更新、重启。启动后按这个流程验证dmesg | grep -i thermal看注册日志确认 zone 和 cooling device 都注册成功ls /sys/class/thermal/确认 zone 和 cooling device 节点都在cat /sys/class/thermal/thermal_zone0/type确认类型名对得上cat /sys/class/thermal/thermal_zone0/trip_point_0_temp确认 trip 温度是设备树里配的值跑压力测试让温度上升观察cooling_device*/cur_state是否变化如果 trip 温度读出来不对多半是设备树没生效或者解析出错。如果 cooling device 没绑定上检查 cooling-maps 里的 phandle 是否正确。这一步我踩过的坑是设备树节点名和驱动里期望的名字不一致导致解析时找不到日志里会有提示仔细看能发现。5. 常见问题与排查技巧实录5.1 温度读数为 0 或明显异常这是最常见的问题。先分清楚是传感器本身的问题还是框架的问题。用 hwmon 直接读传感器如果 hwmon 也读不到那是驱动或硬件问题如果 hwmon 正常但 thermal 读出来是 0那是 thermal 接入的问题。thermal 读 0 常见原因有几个get_temp回调没实现或者返回了错误码但被当成 0单位搞错返回了摄氏度但框架按毫摄氏度处理导致数值小得离谱传感器还没初始化完就被读了。排查时先看驱动里get_temp的实现确认返回值和单位。我遇到过一次是驱动返回了负值表示错误但框架没处理负值直接当温度用了结果温度判断全乱。5.2 cooling device 不生效的排查路径温度到了 trip 但降温没动作按这个顺序查排查点检查方法常见问题cooling device 是否注册ls /sys/class/thermal/cooling_device*驱动没加载是否绑定到 zone看 zone 下 cooling_device 链接cooling-maps 配错governor 是否工作cat policy 看策略governor 没绑定set_cur_state 是否被调用加打印或 ftrace回调没实现档位是否真的生效看硬件实际状态驱动翻译逻辑错我遇到最多的是 cooling-maps 里 phandle 写错或者 cooling device 注册晚于 zone导致绑定时找不到。注册顺序问题在模块化驱动里特别容易出因为加载顺序不确定。解决办法是让 cooling device 驱动在 zone 之前初始化或者用 deferred probe 机制。5.3 governor 选择与调参经验governor 的选择要看场景。step_wise适合单降温设备的场景逻辑简单逐步加档不会过度降温。fair_share适合多设备按比例分配。power_allocator是更高级的策略基于功耗预算分配适合手机这类对功耗敏感的设备但配置复杂需要提供功耗模型参数。调参方面step_wise的关键是 trip 温度和滞后值。trip 设太低会频繁降频影响性能设太高又起不到保护作用。我的经验是 passive trip 设在芯片长期工作温度上限减 5 度左右留点余量。滞后值 2 到 5 度比较合适具体看温度变化速度变化快的场景滞后可以大一点。5.4 系统休眠恢复后温控失效这个问题比较隐蔽。休眠时 thermal 会挂起恢复时要重新初始化。如果恢复流程里漏了某一步比如 governor 状态没重置、cooling device 档位没恢复就会出现恢复后温控不工作的情况。排查时重点看suspend和resume回调确认状态保存和恢复是否完整。我遇到过一次是恢复后 polling 定时器没重新启动导致温度不再更新自然也不会触发降温。解决办法是在 resume 里显式重启 polling。这类问题在框架代码里通常有处理但如果驱动自己实现了 suspend/resume就容易漏。5.5 调试工具与日志技巧thermal 的调试主要靠 sysfs 和 dmesg。sysfs 能看实时状态dmesg 能看注册和错误信息。更深入的话可以用 ftrace 跟踪 governor 的决策过程或者用thermal_debugfs如果内核开了这个选项看更详细的状态。我常用的一个技巧是临时把 polling-delay 调小比如设成 100ms这样温度更新快调试时能更快看到反应。调完记得改回去不然会增加系统开销。另外cat /sys/class/thermal/thermal_zone0/下所有文件过一遍能快速了解这个 zone 的完整配置比翻设备树快。6. 写在最后的一点个人体会thermal framework 这套东西架构设计得相当干净核心就是 zone、governor、cooling device 三者的协作。但实际用起来坑往往不在框架本身而在配置和驱动的交界处——设备树写错、注册顺序不对、单位搞混、恢复流程漏步骤。这些问题框架不会替你兜底得靠自己一点点排查。我的建议是新平台 bringup 时先把 sysfs 手动验证一遍确认链路通了再写设备树这样能省很多来回编译的时间。另外多看 dmesgthermal 的报错信息其实挺友好的大部分问题日志里都有线索。最后trip 温度和滞后值这些参数别照抄别人的一定要结合自己芯片的手册和实际散热条件来定抄来的参数在别的板子上很可能水土不服。

相关新闻

muse-gadget-sdk 中的 Epson 技能:通过 Home Link 用 IPP 打印与 eSCL 扫描

muse-gadget-sdk 中的 Epson 技能:通过 Home Link 用 IPP 打印与 eSCL 扫描

【免费下载链接】muse-gadget-sdk Open source SDK to build Muse gadgets 项目地址: https://gitcode.com/gh_mirrors/mu/muse-gadget-sdk 点击查看 免费下载 本文以仓库中的社区设备技能 skills/gadget-epson-printers/SKILL.md 为主体,讲解 Muse 设备…

2026/10/9 4:35:55 阅读更多 →
IEC 61800-9-2能效架构重组:从磁滞损耗模型到高频开关效率的工程逻辑

IEC 61800-9-2能效架构重组:从磁滞损耗模型到高频开关效率的工程逻辑

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

2026/10/9 4:34:54 阅读更多 →
基于MQTT的温控风扇实战:从温度采集到自动降温的完整实现

基于MQTT的温控风扇实战:从温度采集到自动降温的完整实现

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

2026/10/9 4:34:54 阅读更多 →

最新新闻

SpringBoot瑜伽馆管理系统毕设:设计实现与答辩要点全解析

SpringBoot瑜伽馆管理系统毕设:设计实现与答辩要点全解析

每年到了毕设季,总有一大批人被“选什么题目”卡住。Java方向的项目来来去去就是管理系统、商城、博客这三板斧,但真正能把一个管理系统讲到明白、做出亮点的人其实不多。这次我完整走了一遍SpringBoot瑜伽馆管理系统的设计与实现,从选题、建…

2026/10/9 5:11:21 阅读更多 →
深入解读 s1 仓库中 GSM8K 评测任务:从 Chain-of-Thought 到 Self-Consistency 的完整实战指南

深入解读 s1 仓库中 GSM8K 评测任务:从 Chain-of-Thought 到 Self-Consistency 的完整实战指南

大模型推理模型微调模型推理服务 【免费下载链接】s1 s1: Simple test-time scaling 项目地址: https://gitcode.com/gh_mirrors/s1/s1 点击查看 免费下载 导读 本文以 GSM8K 任务说明文档 为主线,系统讲解在 lm-evaluation-harness 中评测 GSM8K 数学…

2026/10/9 5:11:21 阅读更多 →
OLS线性回归实战指南:从核心假设到残差诊断的完整流程

OLS线性回归实战指南:从核心假设到残差诊断的完整流程

1. 为什么我们还在用两百年前的OLS1.1 一个被低估的“老家伙”最小二乘法(Ordinary Least Squares,OLS)线性回归,这个名字听起来像是统计学课本里第一章就会出现的“老古董”。很多人学完就扔,觉得它太简单、太基础&am…

2026/10/9 5:11:21 阅读更多 →
SeaTunnel FieldMapper 字段映射转换:字段删减、重命名与顺序调整实战指南

SeaTunnel FieldMapper 字段映射转换:字段删减、重命名与顺序调整实战指南

数据工程大数据批处理流处理 【免费下载链接】seatunnel SeaTunnel is a next-generation super high-performance, distributed, massive data integration tool. 项目地址: https://gitcode.com/gh_mirrors/sea/seatunnel 点击查看 免费下载 本文以 SeaTunnel 官…

2026/10/9 5:11:21 阅读更多 →
DeepSeek API在RAG客服系统中的可信生成实践

DeepSeek API在RAG客服系统中的可信生成实践

简介:本资源是一份面向企业技术负责人、AI集成工程师与客服系统开发者的实战型技术文档,聚焦DeepSeek大模型API在知识管理与智能客服两大核心场景的工程化落地。文档系统拆解了从需求分析、架构设计、数据预处理、代码实现到测试优化的全流程&#xff0c…

2026/10/9 5:11:16 阅读更多 →
叉车装上“智慧之眼”:RFID天线如何让仓储搬运秒级精准识别

叉车装上“智慧之眼”:RFID天线如何让仓储搬运秒级精准识别

在电商、制造、冷链等行业高速发展的今天,仓储管理正从“人力驱动”向“数据驱动”转变。叉车作为仓储作业的核心设备,其运行效率与作业准确性直接决定了仓库的整体效能。然而,传统的叉车作业模式中,操作员需频繁停车进行人工扫码…

2026/10/9 5:10:15 阅读更多 →

日新闻

Java时间API实战:LocalDate、Date与ZonedDateTime的转换与避坑指南

Java时间API实战:LocalDate、Date与ZonedDateTime的转换与避坑指南

Java时间API这个话题,隔三差五就会在群里被翻出来讨论一次。上周还有个同事线上处理一个订单超时问题,排查到最后发现是ZonedDateTime序列化后时区丢了,用户在下单当天晚上看到的时间整整差了8个小时。这类问题几乎每个做Java开发的人都遇到过…

2026/10/9 0:00:49 阅读更多 →
EasyTier实践:从NAT穿透到子网代理的异地组网部署与排错

EasyTier实践:从NAT穿透到子网代理的异地组网部署与排错

前几个月我手头有好几台机器需要互相访问:办公室台式机、家里 NAS、还有一台云主机。如果只是偶尔传个文件倒还好,问题是工作场景经常要在几处环境之间来回切换,每次都先登录跳板机再层层代理,实在折腾。我先后试过端口映射、自建…

2026/10/9 0:00:49 阅读更多 →
AI Agent工程实战:从七要素到七个决策点的系统设计指南

AI Agent工程实战:从七要素到七个决策点的系统设计指南

AI Agent 这个词在过去一年里被反复提及,但真正动手搭过一套能跑起来的 Agent 系统的人都知道,从"知道它是什么"到"让它稳定干活"之间隔着一整套工程决策。我前后参与过几个 Agent 项目的落地,从最初用现成框架拼装&…

2026/10/9 0:01:50 阅读更多 →

周新闻

KT148A语音芯片外挂8002D功放的工程实践指南

KT148A语音芯片外挂8002D功放的工程实践指南

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

2026/10/8 15:26:32 阅读更多 →
LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

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

2026/10/8 15:26:40 阅读更多 →
ARM架构深度解析:从RISC设计理念到交叉编译实战

ARM架构深度解析:从RISC设计理念到交叉编译实战

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

2026/10/8 10:10:36 阅读更多 →

月新闻

我发现了一个新思路:用 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/8 21:13:17 阅读更多 →
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/8 15:26:17 阅读更多 →
黑夜航拍船只数据集训练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/7 13:34:55 阅读更多 →