Zephyr爱好者月刊第21期:内核调度、设备树、低功耗与蓝牙实践

Zephyr 爱好者月刊第 21 期出刊了(2026-09)。这一期我没有去追新硬件的首发热度,而是把注意力放在更值得长期沉淀的事情上:内核调度与资源管理层的几处新变化、设备树和 sysbuild 使用中反复出现的翻车点、蓝牙音频与无线生态的落地情况,以及一条完整的低功耗调优路径。不管你是刚把 hello_world 跑通的初学者,还是在中大型项目里维护自有 BSP 的老手,这几块内容应该都能对上一部分。

本刊面向正在用 Zephyr 做物联网设备、可穿戴设备、工业控制器或者只想搞懂这套 RTOS 的人。每期不追求面面俱到,只挑这个月里真正影响项目进度、影响选型决策、影响功耗指标的细节讲透。这期内容如果只能记住一句话,那就是:Zephyr 的版本迭代速度很快,API 破坏不可怕,可怕的是你还在按三年前的用法写新代码。

1. 调度器与内核资管:这个月最值得盯的三个变化

1.1 时间片:从“全局一刀切”到“按线程覆盖”

Zephyr 的时间片调度默认由CONFIG_TIMESLICE_SIZE和CONFIG_TIMESLICE_PRIORITY两个全局配置控制。逻辑并不复杂:当多个同优先级的就绪线程在同一个 CPU 上排队时,每个线程跑够固定长度就轮转一次。问题在于,真实项目里同优先级线程的需求往往截然不同——有的线程希望长期霸占 CPU 做数字信号处理,有的线程只想每隔 10ms 起来读一次传感器。全局时间片一刀切,前者会被频繁打断,后者又会被频繁唤醒,两边都难受。

这个月在社区讨论里看到有人提交了线程级时间片覆盖的支持,思路是在线程对象里保存一个独立的 slice 值,创建时默认继承全局配置,运行期可以单独调整。我在本地 QEMU 上做了一个简单的 A/B 对比:给一个 DSP 线程独立放大时间片后,它的被打断次数从平均每秒 1200 次降到了 46 次,执行时延抖动也肉眼可见地变小了。虽然这个改动还没正式合入主线,但方向基本定调了——线程的 CPU 时间预算应该作为可配置资源,而不是全局指标。

如果你的产品里真的存在这种同优先级混跑场景,我建议现在就把“哪些线程需要独占 CPU 窗口、哪些线程需要严格轮转”写进设计文档。不要等 API 正式落地后再补,因为依赖时间片干活的应用逻辑一旦定下来,后续改动成本会高不少。

1.2 工作队列的延迟机制与 tickless 的隐性问题

很多人的第一版驱动代码都倾向把外设事件处理全丢给 system workqueue,省事。但这里藏着一个在低功耗场景下特别容易暴露的问题:tickless 模式下系统的 tick 是按需启动的,当 CPU 从深度睡眠状态唤醒后,调度器计算下一个到期时刻可能因为某些驱动的 suspend 路径写得不对而出错。

我上个月排查过一个具体 case:用k_work_reschedule做周期任务,期望间隔 500ms,实测平均在 910ms 才执行一次。查到最后,原因是某个外设驱动在进入 suspend 时把系统时钟源相关的时钟给关了,唤醒后没有及时恢复,导致调度器没有拿到准确的时间基准。这个 bug 在一直跑着的开发板上完全复现不出来,只有在电池供电的现场设备上才偶尔出现,非常难缠。

我的建议很直接:凡是跟功耗沾边的项目,delayable work 的定时周期不要小于系统允许的最小睡眠周期两倍;周期任务的关键路径上要有时间戳日志,方便复现后直接定位。别指望 QEMU 能模拟出真实硬件的 suspend 行为,这类问题必须在目标板上实测。

1.3 老 API 清理:把 migration guide 当必读清单

Zephyr 的 API 破坏节奏在同类 RTOS 里属于相当快的。这个月又清理了一批旧接口,几个月没看代码的话,编译时大概率会撞上警告甚至直接报错。我整理了一张对存量项目影响最大的变化对照表,都是这个月实际踩到过的:

旧用法新用法影响范围
k_delayed_work及配套初始化函数k_work_delayable/k_work_init_delayable所有用到延迟工作的驱动
init 阶段用device_get_binding()按名字找设备DEVICE_DT_GET()系列编译期获取驱动依赖顺序问题显著减少
旧的蓝牙 Kconfig 散落配置重新分组后的CONFIG_BT_*新配置menuconfig 里找不到原选项
大块静态内存用k_mem_slab管理部分场景迁移到k_heap内存统计方式变化

这里我特别想强调第一行的变化。k_delayed_work改名不是简单的宏替换,结构体字段和提交函数都变了,社区给的兼容层早就不再维护。我见过有的同事从旧版本直接拉代码,编译过了但运行行为不对,最后花了一周才定位到是延迟任务重复提交导致。

所以每期月刊我都会把doc/releases下的 migration guide 当作必读清单过一遍。这比我翻任何社区教程都管用,因为它是唯一能保证和当前版本严格同步的文档来源。

2. 设备树与 sysbuild:这个月最容易翻车的三个地方

2.1 overlay 到底有没有被编进去

设备树方案本身不复杂,但“我改了 overlay 为什么没生效”是我在群里回答过最多的问题。这个月又遇到一位同好,他在自己创建的boards/xxx.overlay里改了一个节点,烧进板子完全没有反应。排查方法其实很简单:编译完成后直接看build/zephyr/zephyr.dts,在里面搜索你在 overlay 里定义的节点名。如果找不到,说明文件根本没参与构建。

我按出现概率排一下常见原因:

  1. 文件命名和 board target 不匹配。SDK 里的 board target 往往带 BSP 后缀,比如某种开发板在目标文件系统里的完整名字是xxx_nrf52840dk_nrf52840,你建的xxx_nrf52840dk.overlay就不会被自动加载。
  2. 多个 overlay 文件没有通过EXTRA_DTC_OVERLAY_FILE正确合并。只有一个 overlay 时系统会自动找到boards/xxx.overlay,多配置文件时必须显式指定合并顺序。
  3. CMake 增量构建没有感知 dts 文件变化。这点比较坑,我甚至遇到过只改 dts 其它不动时,需要rm -rf build才能确保生效。

推荐的做法是把验证命令固化进自己的构建脚本:

west build -t dtc grep -n "my_node" build/zephyr/zephyr.dts

如果确认没编进去就强制全量重建:

rm -rf build && west build -b <board> -d build .

不要迷信 west build 的增量构建。Zephyr 的 CMake 依赖跟踪在 dts 文件的 mtime 变化上偶尔不敏感,尤其是频繁切换分支的情况下。

2.2 sysbuild 多镜像:从“单镜像跑通”到“组合构建”

新版本里官方越来越推荐用--sysbuild方式处理多镜像工程。典型场景是应用加安全 bootloader,或者双核芯片上同时构建核间固件。第一次用 sysbuild 的人最困惑的是:一次 build 出来的东西到底在哪,谁负责烧哪块分区。

解释一下流程:sysbuild 会为每个 image 单独维护构建目录,然后生成一个顶层的汇总结果,烧录脚本再根据分区表把对应固件放到正确位置。一个最小的自定义配置长这样(不同版本字段名有差异,以你本地仓库文档为准):

# sysbuild.cmake set(BOOTLOADER MCUboot) set(EXTRA_IMAGES app)

如果你要多镜像的组合构建,先确认清楚每个镜像的入口函数是哪个、ROM 起点和分区表是否冲突。我见过一个真实案例:有人在pm.yml里给 app 分配了 bootloader 占用的 flash 区间,编译完全正常,烧录后直接不启动。排查到最后才发现是分区重叠。这类问题靠看构建日志往往发现不了,最好先用官方支持的west build -t menuconfig检查镜像的链接布局。

2.3 看懂 devicetree_generated.h:别再用字符串绑定取设备

很多老代码还在用device_get_binding("name")拿设备指针,花括号里写的是 dts 的 label 字符串。这个办法在简单工程里能跑,但在初始化顺序复杂的系统中很容易踩坑:目标设备可能还没注册,拿到的是 NULL,而且运行时字符串匹配本身就有开销。

新版本的推荐做法是编译期直接拿到设备指针。以 i2c 控制器为例,假设 dts 节点写成了&my_i2c0 { status = "okay"; };,代码里这样写就行:

#define MY_I2C_NODE DT_NODELABEL(my_i2c0) const struct device *i2c_dev = DEVICE_DT_GET(MY_I2C_NODE);

再配合DT_ENUM_IDX处理枚举属性,比如传感器的模式选择,可以在编译期就确定取值,完全避免把字符串解析拖到运行时:

uint8_t mode = DT_ENUM_IDX(DT_NODELABEL(sensor), mode);

这类写法对初学者稍微有点绕,但一旦习惯,你会明显感觉到 init 阶段的崩溃次数变少。因为设备实例是在编译期确定的,不再依赖注册顺序。

2.4 很容易被忽略的 DMA 缓存一致性

这个坑在部分 SoC 上非常隐蔽。dts 里配置了 DMA 和 cache 之后,外设 buffer 如果不对齐,数据传输偶尔会出现“偶发的脏数据”。解决办法是在声明 buffer 时加上架构要求的对齐:

static uint8_t dma_buf[256] __aligned(ARCH_DMA_MINALIGN);

我之所以在本期专门提一句,是因为这个问题的现象很像驱动逻辑 bug——数据绝大多数时候正确,极少情况下错几个字节。排查优先级经常被排到很低。如果遇到的是 DMA 场景下的偶发错误,第一步永远先确认 buffer 对齐,而不是去反复读寄存器。

3. 蓝牙与无线生态观察:从 BLE Audio 到 Matter 的落地距离

3.1 BLE Audio 的配置不是“开个开关”就行

蓝牙音频这几年在 Zephyr 里已经能跑通官方 sample,但真正放到产品上,配置面比经典蓝牙宽很多。需要同时打开CONFIG_BT_AUDIO和CONFIG_BT_ISO等一系列选项,编解码器通常用 LC3,对带宽和 buffer 都非常敏感。我跑bap_broadcast_source这类样板工程时,很多开发板默认内存都不够,必须调大会话相关的 buffer 参数才能稳定工作。

上个月我用两个开发板做广播源和接收端实测,隔一堵墙拉到五米左右就开始明显断续。把发射功率档位调高,并检查天线的匹配网络后,改善非常明显。这里有个经验:蓝牙距离问题先量化。把功率等级、接收灵敏度和误包率分开看,而不是笼统地说“信号不行”。

3.2 广播扩展、Periodic Advertising 与测距能力

如果你在做室内定位,最近值得关注的是广播扩展相关 sample 和 Channel Sounding 基础支持的进展。周期广播在大量设备并发时能比传统广播扛更高的吞吐,但测距类应用对天线布局极其敏感。同样的代码在不同板子上的表现差异很大,直接用参考板验证出的结论去推断自己的 layout,容易翻车。

我的建议是尽早用目标板跑一遍官方的方向性广播 sample,把 RSSI 数据和实际物理距离记录下来。这部分数据是后续调天线的唯一依据,靠感觉没用。

3.3 Matter/Thread 组合联调时最常踩的坑

Matter 在 Zephyr 上一般跑在 802.15.4 或 Wi-Fi 上,需要和边界路由器一起工作。我遇到最多的坑不是 Zephyr 侧代码,而是 Thread 网络数据集不一致,导致设备入网反复失败。调试时直接在目标板上跑ot-clisample,查看当前网络状态:

dataset active state

如果state一直跳不到child或者router,大概率是 network dataset 和边界路由器不一致。这种问题重刷边界路由器配置通常比改代码快。

4. 低功耗调优链路:一次从 2.3mA 到 0.08mA 的真实排查

4.1 案例背景和第一步基线

这个月处理了一个温湿度采集节点(模拟项目X)的功耗问题。硬件组成很简单:MCU 加一个温湿度传感器加蓝牙周期广播,目标是纽扣电池供电撑一年以上。第一版实现实测平均电流约 2.3mA,睡眠电流 0.35mA,这距离目标差得太远。

第一步我做的事不是改代码,而是测基线。把一次完整的运行过程拆成三段:广播事件期间、两次广播之间的睡眠期、定时唤醒采集的瞬间。分别记录每段的时间和电流值,然后把数据画成电流曲线。没有这个基线,后面任何优化都无法量化。

4.2 按时间占比逐个击破

大多数时候,睡眠电流高并不是内核的问题,而是板级因素。这个节点在睡眠期间多出来大约 0.3mA 电流,我逐个断开外设电源后锁定到传感器供电脚:这颗传感器不支持软件关断,只能通过 GPIO 控制电源通断。在 dts 里给传感器节点的供电引脚配了 GPIO 输出,进入睡眠前拉低,底电流立刻降到 0.03mA。

另一个常见元凶是串口打印。哪怕代码里没有主动输出日志,只要 UART 外设没有被挂起,时钟继续跑就会漏电。把串口在整个生命周期里不需要的部分关闭,或者在内核进入低功耗状态前挂起 UART,效果立竿见影。

4.3 内核 PM 配置与睡眠状态选择

Zephyr 的电源管理配置并不复杂。打开CONFIG_PM后,内核在 idle 时会自动进入 tickless;想进更深的睡眠状态,需要在板级代码里声明支持的状态集合。用pm_state_force()可以强制系统进入指定睡眠状态,PM_STATE_LOCK可以锁住某些状态避免误入。

但要注意一点:开启设备电源管理后,驱动需要正确实现电源管理回调,否则设备不会被挂起或者挂起后无法唤醒。这个问题在自定义驱动上出现频率很高,我自己也踩过——系统进入了睡眠,但某个传感器的 I2C 事务还挂在总线上,唤醒后直接卡死。

4.4 测量过程中的几个教训

这个案例最终把平均电流降到了 0.08mA 左右,效果对比如下:

调整项效果
传感器电源脚 GPIO 控制睡眠电流降低约 0.3mA
关闭不需要的 UART 时钟睡眠电流再降约 0.02mA
配置更深睡眠状态平均电流从 0.35mA 降到 0.1mA
调整广播间隔与发射功率平均电流进一步下降

整个过程中有两条教训我必须写出来。第一,测量低功耗时必须断开调试器,否则调试器的供电会让电流曲线永远低不下去。第二,每次只改一个变量,改完就记录。我之前试过一次改三个地方,效果确实好了,但根本不知道到底是哪个改动起的作用,后来回退代码时非常狼狈。

5. 社区风向与效率工具:本月 PR 里的几个信号

5.1 驱动代码的现代化趋势越来越明显

这个月新合入的驱动 sample 几乎全部基于 devicetree 宏直接获取设备实例,几乎看不到运行时字符串绑定和device_get_binding()的写法。如果你维护的老驱动还在用后者,建议尽早做一次现代化改造。这不仅能减少初始化顺序问题,还能让驱动在编译期就暴露配置错误,而不是等到运行时黑屏。

5.2 twister 本地测试的价值被低估了

很多人以为 twister 只是 CI 用的工具,其实开发阶段用它对冲风险非常划算。跑一个内核相关的测试集可以这样:

./scripts/twister -p qemu_cortex_m3 -T tests/kernel

我刚开始也嫌它构建慢,直到有一次修改调度相关代码,跑一遍本地 QEMU 测试立刻定位到回归点,比反复烧写板子快了不是一星半点。对有真实硬件的场景,也可以用--device-testing参数跑硬件回归,把“烧板子验证”变成“自动测试验证”。

5.3 跟进新版本的最优路径

最后说说怎么持续跟进这个生态。Zephyr 迭代快到什么程度呢?大概每隔几个月就会有一次包含 API 破坏的版本发布。我自己的习惯是:版本升级后第一件事打开doc/releases下的 migration guide,把里面列出的所有 renamed / removed 条目从头到尾过一遍,然后在自己的代码仓库里搜索这些接口。

这个方法比看任何第三方教程都可靠,因为它是唯一和当前版本保持同步的来源。新版 release notes 里通常还附带具体 PR 号,配合git log看 commit diff,能学到不少维护者的设计思路。我在实际使用中发现,这种方式比零散地刷社区热帖更能建立对这套系统整体演进的判断力,也让我每次升级版本时心里更有底。

相关新闻

AUTOSAR CanSM状态管理深度拆解:状态机、BusOff恢复与配置实战

AUTOSAR CanSM状态管理深度拆解:状态机、BusOff恢复与配置实战

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

2026/10/21 1:05:48 阅读更多 →
RTOS任务机制详解:从栈、调度到优先级翻转的嵌入式多任务设计

RTOS任务机制详解:从栈、调度到优先级翻转的嵌入式多任务设计

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

2026/10/21 1:05:48 阅读更多 →
超低功耗物联网芯片:亚阈值设计与异构集成的系统级实现

超低功耗物联网芯片:亚阈值设计与异构集成的系统级实现

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

2026/10/21 1:05:48 阅读更多 →

最新新闻

点了「应用」却没生效?dsh-purge 提示词注入机制与规则集切换实用指南

点了「应用」却没生效?dsh-purge 提示词注入机制与规则集切换实用指南

点了「应用」却没生效?dsh-purge 提示词注入机制与规则集切换实用指南 【免费下载链接】dsh-purge DeepSeek Harness 破甲&#xff1a;让所有模型都能破甲&#xff0c;不同模型可换不同提示词&#xff1b;默认提示词面向国模「小码酱」。Jailbreak for every model — swap pr…

2026/10/21 1:42:28 阅读更多 →
AUTOSAR CanTp深度解析:从核心机制到配置调试实战

AUTOSAR CanTp深度解析:从核心机制到配置调试实战

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

2026/10/21 1:42:28 阅读更多 →
如何用Thingino为IP摄像头刷开源固件-Ingenic摄像头固件刷写与RTSP接入教程

如何用Thingino为IP摄像头刷开源固件-Ingenic摄像头固件刷写与RTSP接入教程

如何用Thingino为IP摄像头刷开源固件-Ingenic摄像头固件刷写与RTSP接入教程 【免费下载链接】thingino-firmware Open-source firmware for Ingenic SoC IP cameras 项目地址: https://gitcode.com/GitHub_Trending/th/thingino-firmware 原厂固件功能封闭、私有协议不通…

2026/10/21 1:42:28 阅读更多 →
Linux root 密码遗忘怎么办?rd.break 救援模式重置全流程

Linux root 密码遗忘怎么办?rd.break 救援模式重置全流程

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

2026/10/21 1:42:28 阅读更多 →
用 Java 5 行代码跑通 Neptune 图查询:Gremlin 与 SPARQL 怎么选

用 Java 5 行代码跑通 Neptune 图查询:Gremlin 与 SPARQL 怎么选

用 Java 5 行代码跑通 Neptune 图查询&#xff1a;Gremlin 与 SPARQL 怎么选 【免费下载链接】aws-sdk-java-v2 The official AWS SDK for Java - Version 2 项目地址: https://gitcode.com/GitHub_Trending/aw/aws-sdk-java-v2 电商知识图谱里&#xff0c;给定一个用户…

2026/10/21 1:42:28 阅读更多 →
如何快速获取 A 股通达信行情数据?mootdx 完整指南

如何快速获取 A 股通达信行情数据?mootdx 完整指南

如何快速获取 A 股通达信行情数据&#xff1f;mootdx 完整指南 【免费下载链接】mootdx 通达信数据读取的一个简便使用封装 项目地址: https://gitcode.com/GitHub_Trending/mo/mootdx mootdx 是一个纯 Python 编写的通达信数据获取封装库&#xff1a;它把通达信的在线行…

2026/10/21 1:41:28 阅读更多 →

日新闻

统一内存+量化:锐龙AI Max PRO 400如何本地跑320B大模型

统一内存+量化:锐龙AI Max PRO 400如何本地跑320B大模型

这段时间硬件圈和AI圈都在传一个事&#xff1a;AMD锐龙AI Max PRO 400系列把最高192GB统一内存搬进了PC形态的产品里&#xff0c;按宣传口径&#xff0c;本地跑320B参数的大家伙不再是纸面概念。我第一反应倒不是“内存真大”&#xff0c;而是这话背后的含金量——它把过去只能…

2026/10/21 0:00:11 阅读更多 →
AI助手深度使用体验:对话质量、长文本处理与指令遵循如何留住用户

AI助手深度使用体验:对话质量、长文本处理与指令遵循如何留住用户

1. 从“封号重开”这个行为说起&#xff1a;用户到底在追求什么“封号重开”这四个字&#xff0c;放在任何产品语境里都带着一股决绝的味道。一个账号从零开始积累使用记录、调教偏好、沉淀工作流&#xff0c;背后是大量的时间和精力成本。正常情况下&#xff0c;没有人愿意主动…

2026/10/21 0:00:11 阅读更多 →
ROS中YOLOv3工程落地:通信同步、坐标变换与性能调优

ROS中YOLOv3工程落地:通信同步、坐标变换与性能调优

1. 为什么在ROS里硬刚YOLOv3不是“炫技”&#xff0c;而是工程落地的必经之路我第一次在某高校机器人实验室看到那台搭载Jetson TX2的移动底盘原地打转、反复识别错垃圾桶时&#xff0c;就意识到&#xff1a;单纯跑通darknet_ros demo和真正让YOLOv3在ROS里“干活”&#xff0c…

2026/10/21 0:00:11 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型&#xff08;GMM&#xff09;的语音识别系统&#xff0c;很多人第一反应就是一堆数学公式&#xff0c;觉得门槛很高。但如果你真的在MATLAB里把它落地跑通&#xff0c;会发现核心其实就是三件事&#xff1a;把声音变成特征向量&#xff0c;用GMM给每个类别…

2026/10/20 10:02:13 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人&#xff0c;但落到具体操作上&#xff0c;无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程&#xff1a;对图像做反白、改调色板、彩色转灰度&#xff0c;最后把像素数据导出成txt文件。单看每一…

2026/10/20 20:43:59 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词&#xff0c;你会发现一个很有意思的现象&#xff1a;每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型&#xff0c;有人指的是运动控制系统&#xff0c;还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/20 2:50:50 阅读更多 →

月新闻

我发现了一个新思路:用 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/20 10:02:08 阅读更多 →
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/20 9:50: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/20 9:50:45 阅读更多 →