Tock 内核工作组 2025-10-02 会议纪要解读:SingleThreadValue 迁移与外部依赖策略落地
操作系统嵌入式嵌入式OS【免费下载链接】tockA secure embedded operating system for microcontrollers项目地址https://gitcode.com/gh_mirrors/to/tock点击查看免费下载导读本文基于 Tock 核心工作组Core WG2025 年 10 月 2 日的会议纪要doc/wg/core/notes/core-notes-2025-10-02.md深入解读本次会议敲定的两项关键技术决策以SingleThreadValue逐步替换static mut的 panic 基础设施迁移路线以及为tock-registers引入外部依赖的例外政策。文章将结合当前仓库中 kernel/src/utilities/single_thread_value.rs、kernel/src/platform/chip.rs、kernel/src/deferred_call.rs 与 doc/ExternalDependencies.md 等源码与文档还原讨论背景、实现原理与最终结论帮助读者理解 Tock 如何在不牺牲安全性的前提下推进内核现代化。会议概览与议程本次会议由 Amit Levy、Brad Campbell、Branden Ghena、Hudson Ayers、Johnathan Van Why 与 Leon Schuermann 六位核心工作组成员参加议程集中在三个相互关联的话题上Cargo.lock PR#4605合并进度与构建系统同步问题SingleThreadValue#4519static mut的替代方案如何推广到全部板卡尤其是 panic 基础设施外部依赖政策#4616 与 #4589为tock-registers成为外部依赖而修改政策的两个竞争提案。这三者共同指向一个更大的目标——解除 Tock 对旧式static mut的依赖、跟上 Rust 工具链的演进同时为内核引入受控的外部依赖打开口子。Cargo.lock PR#4605为外部依赖铺路的构建系统同步讨论要点会议首先确认了 Leon 提交的 Cargo.lock PR#4605可以合并。该 PR 之所以需要尽快合并是因为lockfile 必须与 Tock 的构建系统保持同步——一旦仓库内 crate 版本发生变动Cargo.lock也会随之变化长期不合并会产生大量冲突。关于 Cargo.lock 是否与其他文件绑定的问题会议结论是历史上它们曾相互关联但当前已经彼此独立。更重要的是Leon 指出引入外部依赖之后必须能够精确控制依赖版本这正是 Cargo.lock 的职责所在。为什么 Cargo.lock 对 Tock 如此关键Cargo.lock 位于仓库根目录Cargo.lock锁定了工作区所有依赖含传递依赖的精确版本与校验哈希。在会议讨论中Johnathan 与 Brad 进一步强调了它的安全价值cargo 会对依赖进行哈希校验比单纯的 git 哈希更强cargo 的版本解析还会考虑传递依赖transitive dependencies保证整个依赖树的一致性。从 Cargo.toml 的[workspace.dependencies]可以看到tock-registers { version 0.10.0, default-features false }已作为工作区级依赖出现这正是外部依赖讨论落地后的直接产物。可以推断合并 #4605 是让外部依赖版本可控、可审计的第一步。SingleThreadValue#4519替换static mut的迁移工程背景panic 基础设施为什么成为瓶颈Brad 在会上点明了问题的核心panic 基础设施的代码被复制到了几乎所有板卡如今要更新它工作量巨大。这里的panic 基础设施指的是各架构、各板卡为打印 panic 信息而维护的全局状态。更紧迫的约束是只要还存在static mutTock 就无法升级 Rust 工具链。因为新版 Rust 对static mut的引用提出了更严格的借用规则引用static mut在安全代码中不再被允许而半途而废的迁移会阻塞整个版本的发布。从当前仓库可以印证这一判断static mut仍存在于 arch/cortex-m/src/syscall.rs如SYSCALL_FIRED、SVC_SWITCH_TO_APP、APP_HARD_FAULT、SCB_REGISTERS等全局状态、arch/x86/src/interrupts/poller.rs 的SINGLETON以及 arch/riscv/src/lib.rs 的链接器符号_szero、_ezero等。这些正是迁移工作尚未完成的部分。SingleThreadValue 的设计动机SingleThreadValuekernel/src/utilities/single_thread_value.rs是本次迁移的核心替代品。它的设计目标是在不要求T: Sync的前提下把非Sync的值安全地放进全局静态变量。其文档明确说明了取舍逻辑# Implementation Trade-Offs一节自动化执行优先于代码审查Tock 一贯主张用 Rust 的类型系统与 API 强制正确性即使检查发生在运行时运行时检查而非编译期检查截至 2025 年 7 月社区尚不知道如何把这些检查移到编译期接受忘记绑定即失败的接口缺陷类型创建后必须显式绑定到线程类似 Tock 常见的先建对象、后设回调模式漏掉这一步会导致运行时检查永远失败但这种代价换来了可保证的健全性soundness。核心实现三阶段绑定状态机SingleThreadValueT内部持有三个字段value: UnsafeCellMaybeUninitT——被包裹的值构造时不初始化以避免T: Send约束bound_to_thread: AtomicUsize——绑定状态的原子指示器其取值对应BoundToThreadStage枚举thread_id_and_fn: UnsafeCellMaybeUninit(fn() - usize, usize)——记录查询当前线程 ID的函数指针与已绑定的线程 ID。绑定过程是一个严格递增的三阶段状态机#[repr(usize)]枚举见源码第 29-64 行阶段值含义Unbound0尚未绑定thread_id_and_fn未初始化可以被绑定Binding1已通过compare_exchange原子操作预留初始化权防止并发绑定thread_id_and_fn仍未初始化Bound2已绑定到某线程thread_id_and_fn初始化完毕且封存不可再修改两个绑定入口bind_to_threadP: ThreadIdProvider安全方法通过compare_exchange(Unbound → Binding)原子地抢占绑定权依赖cfg(target_has_atomic ptr)即目标平台需支持usize级别的原子比较交换bind_to_thread_unsafeP: ThreadIdProviderunsafe 方法适用于不支持compare_exchange的平台要求调用者在外部保证不会与其他绑定调用并发因此可直接从Unbound跳到Bound省去中间状态。两个方法均在完成thread_id_and_fn与value的初始化后以Ordering::Release将状态存储为Bound确保后续Acquire加载能观察到完整的初始化写入源码第 342-348、439-445 行。访问入口是get() - OptionT内部先调用bound_to_current_thread()该方法以Acquire顺序加载bound_to_thread确认状态为Bound后读取封存的线程 ID并与ThreadIdProvider::running_thread_id()的当前返回值比对一致才返回Some(T)否则返回None。由于只允许同一线程获取共享引用多线程下通过Cell、MapCell等内部可变性容器再获取可变访问这正是 tock-cells 中MapCell/TakeCell的用武之地。类型整体通过unsafe implT Sync for SingleThreadValueT {}标记为Sync源码第 206 行其 SAFETY 注释给出的理由是该类型在运行时强制值只对起源线程可见与标准库LocalKey的语义类似。ThreadIdProvider线程识别的安全前提SingleThreadValue的安全性完全建立在ThreadIdProvider的正确实现之上。该 trait 定义于 kernel/src/platform/chip.rs 第 128-137 行pub unsafe trait ThreadIdProvider { /// Return a unique ID for the currently executing thread. fn running_thread_id() - usize; }它是一个unsafe trait理由很直接实现者必须保证返回的 ID 对当前执行线程唯一且一致否则依赖它的SingleThreadValue会变得不健全。文档同时指出嵌入式平台虽是单核、单执行线程但中断服务例程ISR的执行构成了第二条执行线程因此实现至少要能区分主线程与ISR 上下文。ThreadIdProvider通过Chiptrait 的关联类型type ThreadIdProvider: ThreadIdProvider与具体芯片绑定kernel/src/platform/chip.rs 第 26 行即由各架构/芯片 crate 提供实现。已完成的示例deferred_call 与 debugBrad 在会上强调我们已经有两个示例——一个使用 UART 的简单示例和一个使用 USB 协议栈的复杂示例。仓库中可确认的落地示例有两个示例一deferred_call 子系统kernel/src/deferred_call.rsstatic CTR: SingleThreadValueCellusize SingleThreadValue::new(); static BITMASK: SingleThreadValueCellu32 SingleThreadValue::new(); static DEFCALLS: SingleThreadValue[OptionalCellDynDefCallRefstatic; 32] SingleThreadValue::new();并配套初始化函数initialize_deferred_call_stateP: ThreadIdProvider()及其_unsafe变体第 174-196 行在启动阶段依次绑定三个全局状态。DeferredCall::new()通过CTR.get()读取计数器分配唯一 ID若get()返回None即板卡未先调用初始化函数会直接 panic 并提示DeferredCall state not initialized——这正是文档中忘记绑定即失败设计取舍的实例。示例二debug 子系统kernel/src/debug.rspub static DEBUG_GPIOS: SingleThreadValueMapCellstatic [static dyn hil::gpio::Pin] ... static DEBUG_WRITER: SingleThreadValueMapCellstatic dyn DebugWriter ... static DEBUG_WRITER_COUNT: SingleThreadValueCellusize ...同样提供initialize_debug_gpioP/initialize_debug_gpio_unsafeP与initialize_debug_writer_wrapperP/_unsafe两组初始化入口第 483、498、588、607 行。迁移策略讨论测试、移植指南与增量路线会议的核心分歧在于迁移节奏Brad 的观点两个示例已经足够不需要再等更多示例只要还有static mut就无法升级 Rust、无法发布版本且目前缺乏跟踪迁移进度的手段Leon 的观点#4519 PR 使用了更新后的接口同时覆盖 ARM 与 RISC-V尚未充分测试需要确认 panic 处理程序在所有可达路径上都正常工作避免意外破坏他主动提出在 RISC-V 平台上完成硬件测试Amit 的折中方案Leon 继续按计划做硬件测试同时 Amit 自己投入时间研究如何让迁移增量进行并形成书面策略Hudson 补充了流程建议——Leon 完成硬件测试后把 PR 从 draft 状态转正、合并再由该 PR 充当其他板卡的迁移模板Johnathan 的提议能否把 panic 处理程序实现通过宏macro搬进 kernel crateLeon 基于在 Arty 与 QEMU 上的实践经验回应各架构的 panic 实现存在大量细微差异很难简单地统一抽取最终共识尝试先抹平elide架构差异再增量恢复由 Leon 与 Amit 按该策略推进与会者普遍同意。会议还确认了一个现实的痛点由于板卡需要跟踪 kernel crate 的改动迁移可能无法按板卡逐个增量提交而需要一个大型 PR 一并完成——Brad 称之为现实情况。外部依赖政策#4616 与 #4589为 tock-registers 开放例外两项竞争提案的取舍Amit 提出了两个竞争提案要求各 PR 作者为自己的方案辩护Brad 的 #4616不改变整体政策仅添加一条针对tock-registers的、非常明确的例外条款并解释为什么它是例外Leon 的 #4589提出一条兜底规则catch-all rule允许枚举之外的外部依赖也按类似标准进入。Leon 在听完 Brad 的方案后主动撤回了自己的提案理由是#4616 是他提案的子集枚举例外依赖的方式没有问题而兜底规则我们并不需要。Branden 以样本量为 1表示保留意见Leon 接受。最终 Amit 提议关闭 #4589、按原样批准合并 #4616Hudson 表示已批准Leon 随即关闭了自己的 PR。讨论中澄清的边界如何依赖不在政策范围内Leon 指出 #4616 没有讨论依赖以何种方式被引入git 依赖 vs crates.io vs submodule 等。Johnathan 认为这是工程问题而非政策问题Hudson 也表示认可因此政策刻意排除了这一维度与 Cargo.lock 的耦合Brad 提醒 cargo 会校验依赖哈希Leon 补充 cargo 的校验强于 git 哈希因为它还覆盖传递依赖再次印证了前面 Cargo.lock 讨论的必要性。政策背景与例外理由Tock 的总体政策是内核不引入 Rust 标准库之外的外部依赖详见 doc/ExternalDependencies.md动机是便于审计只审查 Tock 仓库内的代码即可评估安全性尤其是unsafe的使用依赖树不可控外部 crate 通常自带依赖而 cargo截至 2023 年 5 月缺乏审计、禁止依赖树中unsafe的健全工具影响面分级外部依赖加在kernel/、arch/、chips/等被反向依赖的 crate 上影响远大于加在板卡 crate 上因此政策按 crate 类型逐级放宽。tock-registers是唯一被明确批准的内核级外部依赖例外其理由包括促进更严格的向后兼容考虑独立仓库避免破坏性变更藏在 Tock 专属 PR 中鼓励定期发布独立版本追踪让更广泛的社区受益降低外部用户参与门槛有明确的问题与提案入口鼓励独立贡献明确其独立项目地位。例外条款同时限制了tock-registers自身的依赖允许对syn、quote、proc-macro2的依赖理由过程宏需要解析/生成非平凡 Rust 代码且这些 crate 是 Rust 生态的核心机制、子依赖仅unicode-ident一个且无传递依赖以及仅用于单元测试的 dev-dependencies。值得注意的是该政策还列出了另一个例外flux-rs精化类型形式化验证仅作可选测试依赖但本次会议讨论聚焦于tock-registers。落地现状印证从当前仓库的 Cargo.toml 可以看到tock-registers已作为[workspace.dependencies]中的外部依赖版本0.10.0default-features false被引入且仓库根目录存在 Cargo.lock。这印证了本次会议决策已实际落地Tock 内核在零外部依赖的底线上为自维护的高价值 crate 开了一条受控、明确、可审计的例外通道。会议结论与后续行动综合三部分讨论本次会议形成了以下明确结论Cargo.lock#4605立即合并保持与构建系统同步为外部依赖的版本控制铺路SingleThreadValue#4519Leon 在 RISC-V 硬件上完成测试、验证 ARM 侧无回归后将 PR 转正并合并由该 PR 作为其他板卡的迁移模板Amit 负责研究增量迁移策略并书面化尝试先抹平各架构 panic 实现的差异再增量恢复外部依赖政策关闭 #4589按原样合并 Brad 的 #4616——以明确例外而非兜底规则的方式为tock-registers打开政策口子。延伸阅读会议纪要原文doc/wg/core/notes/core-notes-2025-10-02.mdSingleThreadValue完整实现与文档kernel/src/utilities/single_thread_value.rsThreadIdProvidertrait 定义kernel/src/platform/chip.rs迁移示例一deferred_callkernel/src/deferred_call.rs迁移示例二debugkernel/src/debug.rs外部依赖政策全文doc/ExternalDependencies.md工作区依赖声明Cargo.toml尚未迁移的static mut现场arch/cortex-m/src/syscall.rs、arch/x86/src/interrupts/poller.rs、arch/riscv/src/lib.rs赞分享操作系统嵌入式嵌入式OS【免费下载链接】tockA secure embedded operating system for microcontrollers项目地址https://gitcode.com/gh_mirrors/to/tock点击查看免费下载相关推荐Tock 核心工作组 2025-09-10 会议纪要解读LLM 贡献政策、tock-registers 外部化与 SingleThreadValueTock 核心工作组 2025 09 10 会议纪要解读LLM 贡献政策、tock registers 外部化与 SingleThreadValue 导读 本操作系统嵌入式嵌入式OSanarlog 桌面端 SQLite 响应式 UI 实战useDrizzleLiveQuery 六大稳定模式与反模式清单anarlog 桌面端 SQLite 响应式 UI 实战useDrizzleLiveQuery 六大稳定模式与反模式清单 本文是一份面向 anarlog 桌面操作系统嵌入式嵌入式OSTock 网络工作组 2025-02-10 会议纪要解读Ethernet Datapath HIL、StreamingProcessSlice 迁移与 libtock-rs 路线讨论Tock 网络工作组 2025 02 10 会议纪要解读Ethernet Datapath HIL、StreamingProcessSlice 迁移与 lib操作系统嵌入式嵌入式OS上一篇Ultimate Vocal Remover 人声分离与伴奏提取5 步跑通 UVR5 的完整指南下一篇Fay框架代码注释覆盖率检查提升文档质量的完整指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

Pikiwidb(Pika)主从同步机制深度解析:全量同步与增量同步的实现原理

Pikiwidb(Pika)主从同步机制深度解析:全量同步与增量同步的实现原理

数据库KV存储后端 【免费下载链接】pika Pikiwidb is a Redis-Compatible database developed by Qihoos infrastructure team. 项目地址: https://gitcode.com/gh_mirrors/pi/pika 点击查看 免费下载 Pikiwidb(Pika)通过 master/slave 主从…

2026/10/10 1:40:42 阅读更多 →
Apache Zeppelin 动态表单(Dynamic Form)完整指南:模板语法与编程式创建

Apache Zeppelin 动态表单(Dynamic Form)完整指南:模板语法与编程式创建

后端前端大数据数据分析 【免费下载链接】zeppelin Web-based notebook that enables data-driven, interactive data analytics and collaborative documents with SQL, Scala and more. 项目地址: https://gitcode.com/gh_mirrors/zeppelin2/zeppelin 点击查看 免…

2026/10/10 1:40:42 阅读更多 →
PCA9422+PIC32MZ构建高可靠嵌入式电源管理系统

PCA9422+PIC32MZ构建高可靠嵌入式电源管理系统

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

2026/10/10 1:40:42 阅读更多 →

最新新闻

为什么你的 Node 测试会卡死?skills 项目教你诊断 flaky 测试与悬挂进程的完整指南

为什么你的 Node 测试会卡死?skills 项目教你诊断 flaky 测试与悬挂进程的完整指南

为什么你的 Node 测试会卡死?skills 项目教你诊断 flaky 测试与悬挂进程的完整指南 【免费下载链接】skills My own collection of skills for modern Node.js development 项目地址: https://gitcode.com/gh_mirrors/skills15/skills skills 是一个面向现代…

2026/10/10 2:28:59 阅读更多 →
如何读懂 NPUSim 指令流水图:Perfetto 可视化操作与关键字段全解

如何读懂 NPUSim 指令流水图:Perfetto 可视化操作与关键字段全解

如何读懂 NPUSim 指令流水图:Perfetto 可视化操作与关键字段全解 【免费下载链接】npu-simulator NPUSim(全称NPU Simulator)是一款面向算子开发场景的SoC级芯片仿真工具,用于分析运行在AI仿真器上的AI任务在各阶段的精度和性能数…

2026/10/10 2:28:59 阅读更多 →
developer-roadmap 中的 Angular 路由转换动画(Route Transitions)实战指南:为页面切换注入流畅过渡

developer-roadmap 中的 Angular 路由转换动画(Route Transitions)实战指南:为页面切换注入流畅过渡

文档教程知识库 【免费下载链接】developer-roadmap Interactive roadmaps, guides and other educational content to help developers grow in their careers. 项目地址: https://gitcode.com/GitHub_Trending/de/developer-roadmap 点击查看 免费下载 当用户从一…

2026/10/10 2:28:59 阅读更多 →
Kubernetes Python Client 探针模型解析:V1HTTPGetAction 类完整指南

Kubernetes Python Client 探针模型解析:V1HTTPGetAction 类完整指南

后端云原生容器编排 【免费下载链接】python Official Python client library for kubernetes 项目地址: https://gitcode.com/gh_mirrors/python1/python 点击查看 免费下载 本篇技术指南聚焦 Kubernetes 官方 Python 客户端(kubernetes-python-client…

2026/10/10 2:28:59 阅读更多 →
Unison Records 语法保真:从 `view` 往返验证到 Record 访问器的源码实现剖析

Unison Records 语法保真:从 `view` 往返验证到 Record 访问器的源码实现剖析

编程语言编译器语言运行时开发工具 【免费下载链接】unison A friendly programming language from the future 项目地址: https://gitcode.com/gh_mirrors/un/unison 点击查看 免费下载 Unison 语言中的 Record(记录类型)是一类以花括号 { …

2026/10/10 2:28:59 阅读更多 →
TVA具身智能系统简介(12):三层核心架构的定义与层级划分

TVA具身智能系统简介(12):三层核心架构的定义与层级划分

前沿技术探索:TVA智能体(简称TVA,亦称“TVA视觉智能体”或“AI智能体视觉”)是依托Transformer架构与“因式智能体”理论构建的通用视觉技术框架。它深度融合深度强化学习(DRL)、卷积神经网络(C…

2026/10/10 2:27:59 阅读更多 →

日新闻

卫星轨道分类全解析:从LEO到GEO的选型逻辑与工程实践

卫星轨道分类全解析:从LEO到GEO的选型逻辑与工程实践

1. 从“卫星轨道分类”这个标题说起:为什么值得花时间搞懂第一次接触“卫星轨道分类”这个概念,很多人会觉得它离自己很远——不就是天上的星星怎么转吗?但如果你正在做航天任务规划、遥感数据接收、星座设计,甚至只是准备一场航天…

2026/10/10 0:00:39 阅读更多 →
Spring AOP 核心原理与实战:从概念到日志切面落地

Spring AOP 核心原理与实战:从概念到日志切面落地

1. 从一个真实痛点说起:为什么你的代码里到处都是重复逻辑刚入行那会儿,我写过一个用户管理模块,注册、登录、改密码、注销四个接口。每个接口里都塞了几乎一样的日志打印、参数校验、事务开启和提交。当时觉得没什么,能跑就行。直…

2026/10/10 0:00:40 阅读更多 →
Python招聘数据采集与分析可视化:从采集清洗到薪资技能城市可视化全链路

Python招聘数据采集与分析可视化:从采集清洗到薪资技能城市可视化全链路

简介:这是一套面向计算机相关专业学生与项目实战学习者的Python数据采集与分析可视化完整项目,以Boss直聘岗位数据为对象,适合用作毕业设计、课程设计或期末大作业。资源包共38个文件,约246KB,以13个py源码文件为核心&…

2026/10/10 0:00:40 阅读更多 →

周新闻

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/10 1:36:08 阅读更多 →
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/9 10:11:06 阅读更多 →

月新闻

我发现了一个新思路:用 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/9 21:32:20 阅读更多 →
黑夜航拍船只数据集训练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/9 6:17:20 阅读更多 →