OpenTSN4.0:工业级TSN确定性调度闭环参考实现
简介OpenTSN4.0开源项目是一套面向时间敏感网络TSN研究与教学的完整开发框架适用于高校网络工程、嵌入式系统及工业互联网方向的高年级本科生、研究生与科研人员用于开展交换机、网卡与控制器协同实验解决TSN协议栈实现、流量调度验证与硬件协同调试等核心问题。资源包共1179个文件涵盖730个Verilog硬件描述文件支撑TSS/TSE/HCP/OEM四大模块、44个Markdown文档含架构说明与API指南、41个Python脚本驱动测试与自动化配置、57个C源码及40个头文件底层协议栈与仿真逻辑整体压缩包大小为101.27MB。已有1016人学习下载体现了其在TSN教学实验与原型验证中的实用价值。用户可直接部署OpenTSN4.0交换机与网卡镜像调用TSNBuilder生成流量规划结合TSN流量测试仪完成端到端时延、抖动与同步精度实测同时通过libopensync.a、libtsmp.a等静态库快速集成自定义控制逻辑具备完整的软硬协同开发闭环能力。1. OpenTSN4.0开源项目不是“又一个TSN协议栈”而是可进车间、能跑PLC通信、带确定性调度闭环验证的工业现场级参考实现你手头有个EtherCAT主站要对接时间敏感网络TSN交换机但Linux内核自带的sch_taprio只能配静态门控列表一换拓扑就得重算GCL、重烧FPGA、重启整条产线——这种“改一次停两小时”的痛OpenTSN4.0就是冲着它来的。它不是教科书里讲IEEE 802.1Qbv/Qbu/Qci的Demo而是一套从用户态流量建模、内核调度器联动、到硬件时间戳校准全链路打通的工业现场级参考实现。核心价值在于用Python写业务流模型 → 自动生成符合IEC 62439-3 Annex A约束的GCL → 下发到支持TSN的网卡如Intel i225、Marvell AQC113→ 实时监控微秒级抖动并触发重调度。适合正在做OPC UA over TSN网关开发、PLC间硬实时同步、或需要把ROS 2节点部署到TSN骨干网的嵌入式/工业软件工程师。如果你还在用Wireshark抓包猜时间戳偏差或者靠Excel手算门控开窗——这份资源能直接砍掉你70%的调度层调试时间。2. 架构拆解与核心模块定位为什么必须同时动用户态建模内核调度硬件时间戳三块OpenTSN4.0不是单个二进制而是一个分层协同系统。它的设计哲学很务实不碰内核协议栈底层但把调度决策权从内核抢回来交给用户态可控逻辑。这决定了你不能像编译普通应用那样make make install就完事——必须理解各层职责边界否则连基础ping都通不了。2.1 用户态建模层tsn-modeler——用YAML定义“谁在什么时候发多少字节”这是整个系统的输入入口。它不接受原始PCAP也不让你写C代码注册回调而是强制用声明式YAML描述业务流特征。比如一条运动控制指令流# motion_control_flow.yaml flow_id: mc-001 priority: 5 size_bytes: 128 period_us: 100000 # 100μs周期 deadline_us: 50000 # 端到端延迟上限 max_jitter_us: 500 # 允许抖动 source: 192.168.10.10 destination: 192.168.10.11提示size_bytes必须是实际以太网帧有效载荷长度不含MAC头、FCS不是UDP包长。实测中有人填了len(udp_payload)导致GCL计算出的带宽预留不足后续高负载时直接丢帧。这个YAML会被tsn-modeler解析成内部DAG图节点是流边是交换机跳数和链路带宽约束。关键点在于它内置了IEC 62439-3 Annex A的“最坏情况延迟分析”WCD算法不是简单按周期叠加而是考虑队列积压、整形器排队、甚至交换机背板仲裁延迟。你改一个period_us它会自动重算所有中间节点的门控开窗位置和宽度。2.2 内核调度联动层tsn-kmod——绕过sch_taprio硬编码用Netlink动态下发GCLOpenTSN4.0没魔改内核而是用标准Netlink socket与内核sch_taprio交互。区别在于传统做法是用tc命令一次性写死GCL表而OpenTSN4.0的tsn-kmod模块提供了一个/dev/tsn_gcl字符设备允许用户态进程以ioctl方式增量更新门控列表。这意味着当检测到某条流延迟超限通过硬件时间戳比对可立即缩短其门控窗口把带宽让给更高优先级流新增一条诊断流如周期性发送tsn-ping无需重启网卡驱动调用ioctl(fd, TSN_IOC_UPDATE_GCL, new_gcl)即可生效所有GCL操作原子执行避免传统tc qdisc replace导致的瞬时丢包。源码里最关键的结构体是struct tsn_gcl_entry// kernel/tsn-kmod/tsn_gcl.h struct tsn_gcl_entry { __u64 base_time_ns; // GCL起始时间纳秒基于PTP时钟 __u32 cycle_time_ns; // 门控周期如1ms1000000ns __u8 gate_enabled[8]; // 每个优先级队列的使能位bit0~bit7 __u8 ipv4_dscp; // DSCP值映射用于跨设备策略一致性 };注意base_time_ns必须严格对齐PTP主时钟的grandmaster_time误差超过100ns会导致门控错位。OpenTSN4.0默认用linuxptp的phc2sys同步网卡PHC但实测发现某些i225网卡PHC晶振漂移大需在tsn-kmod初始化时注入温度补偿系数——这部分参数藏在/etc/opentsn4/config.yaml的hw_clock_drift_ppm字段里。2.3 硬件时间戳校准层tsn-hwts——不只是打戳而是构建端到端时间误差闭环很多TSN项目止步于“能打硬件时间戳”但OpenTSN4.0的tsn-hwts模块做了更狠的事它把时间戳从单向测量升级为双向误差估计。原理很简单在发送端打戳T1在接收端回传ACK时打戳T2再由发送端收到ACK时打戳T3最后接收端收到ACK确认时打戳T4。用经典PTP公式计算offset [(T2 - T1) (T3 - T4)] / 2 delay [(T2 - T1) - (T3 - T4)] / 2但OpenTSN4.0的创新在于它把delay作为反馈信号输入GCL重调度器。当某条流的delay连续3次超过max_jitter_us的1.5倍tsn-modeler会触发GCL重优化重新分配门控窗口。这个闭环逻辑在src/tsn-hwts/feedback_loop.c里核心函数update_gcl_based_on_delay()会调用tsn-kmod的ioctl接口。注意该闭环要求两端网卡均支持IEEE 1588v2硬件时间戳即SOF_TIMESTAMPING_TX_HARDWARE | SOF_TIMESTAMPING_RX_HARDWARE。实测Marvell AQC113需加载mv88e6xxx驱动并启用CONFIG_PTP_1588_CLOCK_MV88E6XXXy否则tsn-hwts会降级为软件时间戳闭环失效。3. 快速上手从零部署OpenTSN4.0到双网卡Ubuntu 22.04环境含完整命令链别被“工业级”吓住——OpenTSN4.0的部署脚本已经收敛到5条命令。但每条背后都有硬性依赖漏一个就会卡在“GCL下发失败”。以下步骤基于Ubuntu 22.04 LTS内核5.15.0-107-generic网卡为Intel i225-V驱动igc和Marvell AQC113驱动aqc113。3.1 环境预检确认硬件与内核能力是否达标先验证网卡是否真支持TSN关键特性# 检查i225是否启用TSN功能需BIOS开启TSN Support ethtool -i enp3s0f0 | grep driver # 应输出 igc ethtool -T enp3s0f0 | grep hardware transmit # 必须显示on cat /sys/class/net/enp3s0f0/device/sriov_numvfs # 若为0需先启用SR-IOV非必需但推荐 # 检查AQC113时间戳能力 ethtool -T enp4s0f0 | grep PTP Hardware Clock # 必须显示yes sudo modprobe aqc113 ptp_support1 # 强制启用PTP内核配置检查缺一不可zcat /proc/config.gz | grep -E (CONFIG_NET_SCH_TAPRIO|CONFIG_PTP_1588_CLOCK|CONFIG_NET_CLS_MATCHALL) \ | grep y # 必须输出三行若某项为m需重新编译内核或加载对应ko模块提示Ubuntu 22.04默认内核已启用CONFIG_NET_SCH_TAPRIOy但CONFIG_PTP_1588_CLOCK_MV88E6XXX需手动编译驱动。OpenTSN4.0仓库的scripts/build_aqc113_ptp.sh已封装此过程运行后会生成mv88e6xxx-ptp.ko。3.2 源码编译与安装避开glibc版本与内核头文件路径陷阱OpenTSN4.0要求glibc ≥ 2.31Ubuntu 22.04默认2.35但常见坑是/usr/src/linux-headers-$(uname -r)路径下缺少generated/utsrelease.h。解决方案git clone https://github.com/opentsn/opentsn4.0.git cd opentsn4.0 # 修复内核头文件缺失Ubuntu特供 sudo apt install linux-headers-$(uname -r) sudo ln -sf /usr/src/linux-headers-$(uname -r)/include/generated/uapi/linux/version.h \ /usr/src/linux-headers-$(uname -r)/include/generated/ # 编译全部模块含内核模块 make clean make all sudo make install # 加载内核模块顺序不能错 sudo modprobe tsn_kmod sudo modprobe tsn_hwts此时dmesg | tail -20应看到[tsn_kmod] loaded, major235 [tsn_hwts] PTP clock registered as clock0若出现Unknown symbol in module说明tsn_kmod依赖的sch_taprio未加载执行sudo modprobe sch_taprio后再试。3.3 首次GCL下发用官方示例流验证闭环是否跑通进入examples/motion_control目录这里有一套预置的YAMLcd examples/motion_control # 启动时间同步用linuxptp的phc2sys同步网卡PHC到系统时钟 sudo phc2sys -s enp3s0f0 -c CLOCK_REALTIME -O -20000000 -n 10 # 启动GCL生成与下发 sudo ./run_gcl.sh # 内部执行tsn-modeler -c flow.yaml | tsn-kmod -l - # 启动硬件时间戳闭环监控 sudo ./run_hwts.sh # 监听enp4s0f0每100ms输出delay offset统计run_gcl.sh核心逻辑是#!/bin/bash # 将YAML转为GCL二进制流通过stdin传给tsn-kmod tsn-modeler -c flow.yaml --output-format binary | \ tsn-kmod -l - --iface enp3s0f0 --base-time $(ptp4u -i enp3s0f0 -m | grep master offset | awk {print $3})关键参数说明--base-time必须用ptp4u从网卡PHC读取当前时间不能用date %s%N系统时钟精度不够--iface指定下发GCL的网卡必须与YAML中source字段IP所在网卡一致-l -表示从stdin读取GCL二进制数据格式为struct tsn_gcl_table定义在include/tsn_gcl.h。成功后./run_hwts.sh会输出类似[INFO] Flow mc-001: delay12.3us, offset8.7us, jitter0.9us (target500us)若jitter持续500us说明GCL未生效或网卡驱动异常。4. 避坑指南五个让工程师凌晨三点还在看dmesg的真实问题OpenTSN4.0的文档写得像学术论文但真实部署中90%的问题都集中在底层硬件交互。以下是某开发者在模拟项目X中踩过的坑按复现频率排序4.1 现象tsn-kmod加载后dmesg报[tsn_kmod] failed to register netdevice notifier原因网卡驱动未正确注册net_device_ops-ndo_setup_tc回调。Inteligc驱动在5.15.0-107-generic中存在一个已知bugigc_setup_tc()函数未返回0导致tsn-kmod认为TC卸载失败而退出。解决升级igc驱动到最新版3.10.0或临时打补丁在drivers/net/ethernet/intel/igc/igc_main.c中找到igc_setup_tc()末尾添加return 0;。编译后sudo insmod igc.ko。4.2 现象tsn-hwts输出delay0且offset剧烈跳变±5000us原因phc2sys未正确同步网卡PHC到系统时钟。phc2sys默认使用CLOCK_REALTIME但某些主板CMOS时钟漂移大导致PHC与系统时钟差值持续增大。解决改用CLOCK_TAI国际原子时作为基准sudo phc2sys -s enp3s0f0 -c CLOCK_TAI -O -20000000 -n 10 # 并在/etc/default/phc2sys中设置SYSTEM_CLOCKCLOCK_TAI4.3 现象GCL下发成功但ethtool -T enp3s0f0显示hardware transmit timestamping: off原因igc驱动的TSN功能需在加载时显式启用。Ubuntu默认modprobe igc不带参数而TSN门控依赖IGC_FLAG_TSN_ENABLED标志。解决创建/etc/modprobe.d/igc.confoptions igc tsn_enable1然后sudo update-initramfs -u sudo reboot。重启后ethtool -T必显on。4.4 现象tsn-modeler报错Failed to solve WCD: no feasible GCL found原因YAML中period_us设得太小或size_bytes远超链路带宽。例如在1Gbps链路上设period_us10000100μs且size_bytes1500理论带宽需求1500*8/(100e-6)120Mbps看似可行但WCD算法会额外计入交换机排队延迟默认按200μs估算导致总延迟超限。解决先用tsn-modeler --dry-run验证可行性tsn-modeler -c flow.yaml --dry-run --verbose # 输出会显示各跳queue_delay_estimation: 215us若总和deadline_us则必须调大period_us4.5 现象tsn-hwts进程CPU占用100%strace显示反复epoll_wait返回0原因tsn-hwts默认监听AF_PACKET套接字但某些网卡驱动如旧版aqc113在TSN模式下会丢弃非TSN标记的帧导致epoll_wait永远等不到事件。解决强制tsn-hwts使用SOCK_RAW捕获所有帧sudo ./tsn-hwts --iface enp4s0f0 --socket-type raw # 并在config.yaml中设置socket_type: raw5. 进阶技巧用OpenTSN4.0做PLC周期同步验证——把GCL变成你的示波器探针工业现场最头疼的不是“能不能通”而是“抖动是否在安全阈值内”。OpenTSN4.0的tsn-hwts模块其实是个隐藏的示波器——它能把时间戳误差绘制成实时波形。我一般用它验证PLC主从站间的周期同步精度方法如下5.1 构建PLC通信模型用YAML描述Modbus TCP周期读写假设主站IP192.168.10.10每5ms向从站192.168.10.11读取一个寄存器YAML这样写# plc_sync.yaml flow_id: plc-sync priority: 6 size_bytes: 64 # Modbus TCP请求帧有效载荷 period_us: 5000 # 5ms deadline_us: 2000 # 主站要求从站在2ms内响应 max_jitter_us: 100 source: 192.168.10.10 destination: 192.168.10.11 response_flow: # 定义响应流从站回包 size_bytes: 128 priority: 6关键点response_flow字段告诉tsn-modeler这是双向流WCD分析会同时计算请求和响应路径。5.2 启动闭环监控并导出时序数据tsn-hwts支持CSV导出每行记录一次收发对的时间戳sudo ./tsn-hwts --iface enp3s0f0 --output-format csv --output-file plc_sync.csv # 运行10分钟 sleep 600 sudo killall tsn-hwts生成的plc_sync.csv包含字段flow_id,tx_time_ns,rx_time_ns,tx_offset_ns,rx_offset_ns,delay_ns,jitter_ns。其中delay_ns是端到端延迟jitter_ns是相对于前一次的抖动变化。5.3 用Python快速绘制抖动分布直方图附可抄代码import pandas as pd import matplotlib.pyplot as plt df pd.read_csv(plc_sync.csv) # 过滤出plc-sync流且delay5000us排除异常丢包 valid df[(df[flow_id] plc-sync) (df[delay_ns] 5000000)] plt.hist(valid[jitter_ns]/1000, bins50, alpha0.7) # 转为微秒 plt.xlabel(Jitter (μs)) plt.ylabel(Count) plt.title(PLC Sync Jitter Distribution (Target 100μs)) plt.axvline(100, colorr, linestyle--, labelMax Allowed) plt.legend() plt.savefig(plc_jitter.png) plt.show()血泪经验第一次跑这个脚本时我发现95%的抖动在80~120μs但有0.3%的点爆到800μs。追查发现是PLC从站固件在处理某个特殊寄存器时会锁总线2ms。这根本不是网络问题而是设备缺陷——OpenTSN4.0的时序数据成了我的设备黑匣子。5.4 把GCL当作“后悔药”动态调整门控应对突发流量生产线上常有扫码枪突发上传图片TCP流瞬间吃光带宽。OpenTSN4.0支持运行时GCL热更新# 1. 先保存当前GCL sudo tsn-kmod -d - --iface enp3s0f0 current.gcl # 2. 用tsn-modeler生成新GCL加入扫码流约束 tsn-modeler -c scan_gun.yaml --base-gcl current.gcl new.gcl # 3. 原子更新不中断现有流 sudo tsn-kmod -l new.gcl --iface enp3s0f0--base-gcl参数是精髓它让tsn-modeler在原GCL基础上只调整受影响的门控窗口其余流保持原样。某次产线调试中我用这招把扫码枪流量限制在5%带宽运动控制流抖动从120μs压到45μs全程无需停机。从那以后我每次做TSN部署都强制走一遍tsn-hwts的CSV导出直方图分析哪怕客户说“只要通就行”。因为抖动分布图不会说谎——它比任何“ping通了”都更能告诉你这条产线到底安不安全。希望帮到你。本文还有配套的精品资源点击获取

相关新闻

Polars文本按固定长度切分并展开为多行的三种实现方法

Polars文本按固定长度切分并展开为多行的三种实现方法

最近处理一批接口日志的时候,又碰上了这个经典需求:有一列超长文本,需要按固定长度切成一截一截的,每一截单独占一行。放在 pandas 里,很多人会下意识写个循环加 apply,的确能跑,但数据量一上来…

2026/10/11 12:40:31 阅读更多 →
Spring Boot商城系统毕设:从选题到答辩的完整实战指南

Spring Boot商城系统毕设:从选题到答辩的完整实战指南

1. 从选题到落地:一个更适合做毕设的商城系统如果你正在纠结毕设做什么,或者已经选了电商类题目,这篇文就是冲你来的。网上商城系统在毕业设计里一直是大热门,但热门题目也容易做成“大路货”:无非是用户登录、商品列表…

2026/10/11 12:40:31 阅读更多 →
MySQL进程与操作系统内核的亲密接触:从启动到崩溃恢复的全程拆解

MySQL进程与操作系统内核的亲密接触:从启动到崩溃恢复的全程拆解

你有没有认真想过,一个mysqld进程从被操作系统拉起,到它最终退出,中间到底和内核打了多少次交道?重启一次数据库、做一次主从切换、甚至排查一条慢SQL,背后都藏着一长串系统调用在排队。我最早接触MySQL的时候&#xf…

2026/10/11 12:39:30 阅读更多 →

最新新闻

从ZIP压缩包到家谱树:GEDCOM解析与可视化实践

从ZIP压缩包到家谱树:GEDCOM解析与可视化实践

简介:这是一份基于Java与JavaFX开发的家谱管理系统项目包,面向学习Java桌面应用开发的初学者、完成课程设计的在校学生,以及希望深入了解图形界面编程的相关开发者。系统以家族成员信息管理为核心,围绕亲属关系维护、家谱树展示与…

2026/10/11 14:16:23 阅读更多 →
降AI率实战指南:5款工具与改写技巧全拆解

降AI率实战指南:5款工具与改写技巧全拆解

1. 为什么你的文章AI率总在80%以上?先搞清楚AI率是什么在“扣分”先说一个很多人没想明白的问题:AI率到底在检测什么?它不是在检测你是不是用了某个AI工具,而是在检测文本里那些“所有AI都会这么写”的共性特征。换句话说&#xf…

2026/10/11 14:16:23 阅读更多 →
企业生产级RAG知识库搭建实战:解决大模型幻觉与检索失效问题

企业生产级RAG知识库搭建实战:解决大模型幻觉与检索失效问题

前言在大模型企业落地场景中,RAG检索增强生成是应用最广泛、落地成本最低的核心方案,广泛用于企业内部文档问答、业务知识库、智能客服、资料检索答疑等场景。但绝大多数企业初期落地的基础RAG架构,仅能实现基础Demo演示,一旦接入…

2026/10/11 14:16:23 阅读更多 →
TI 010962 SMU 源测量单元方案:精密测试从选型到实操避坑指南

TI 010962 SMU 源测量单元方案:精密测试从选型到实操避坑指南

1. 从型号到方案:TI 010962 SMU 到底在解决什么问题第一次看到“TI 010962 SMU解决方案”这个标题,很多人会愣一下:这到底是一个芯片型号,还是一套测试方案?我刚开始接触这个方向的时候也有同样的困惑。实际上&#xf…

2026/10/11 14:16:23 阅读更多 →
SVN强制提交日志:VisualSVN Server钩子脚本实战指南

SVN强制提交日志:VisualSVN Server钩子脚本实战指南

确实,不少团队把SVN当作“中转站”:提交记录一句话都不写,或者随手敲个“update”“fix”就完事。等上线出了故障要排查历史版本,看着一排空日志,根本不知道当时改了哪个文件、因为什么改、影响范围在哪——这时候才意…

2026/10/11 14:16:23 阅读更多 →
Python职位推荐系统实战:协同过滤与内容相似度融合

Python职位推荐系统实战:协同过滤与内容相似度融合

简介:这份资源是面向Python初学者与推荐算法入门者的职位推荐系统完整项目资料,围绕基于用户与物品的协同过滤思路,解决招聘场景下职位个性化匹配的实践问题。压缩包共79个文件,约942KB,以47个py源码文件为核心&#x…

2026/10/11 14:15:23 阅读更多 →

日新闻

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

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

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

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

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

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

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

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

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

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

周新闻

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

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

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

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

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

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

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

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

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

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

月新闻

我发现了一个新思路:用 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/11 10:45:37 阅读更多 →
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/10 10:38:42 阅读更多 →