Linux 8250 驱动深度解析:TIOCMGET/TIOCMSET 与 RTS 硬件流控实战
1. 从一个真实调试场景说起为什么要啃 8250 驱动很多人第一次接触 Linux 串口都是从open(/dev/ttyS0)加termios配置波特率开始的用起来确实简单。但一旦遇到硬件流控不生效、RTS 电平控制不了、TIOCMGET返回的状态位对不上就会卡住——因为问题已经下沉到驱动层了。我最近在 x86 平台上调一块外接的 16550A 兼容串口芯片就完整踩了一遍这条链路应用层ioctl到 tty 层再到 8250 驱动最后落到 UART 寄存器。整个过程走通之后我觉得有必要把这条路径完整梳理一遍尤其是TIOCMGET、TIOCMSET和 RTS 这三者之间的关系因为这是最容易混淆的地方。这篇文章面向的是已经会用串口、但想搞清楚底层到底发生了什么的人。我会以 x86 平台上的 8250 驱动为主线把 16550A 这个经典 UART 的寄存器模型、Linux 串口驱动的分层结构、TIOCMGET/TIOCMSET的实现路径以及 RTS 硬件流控和手动控制 RTS 的区别全部拆开讲清楚。文中会给出可以直接参考的代码片段和调试命令也会分享几个我在实测中踩过的坑。如果你正在做嵌入式串口通信、工业设备对接或者单纯想读懂内核里8250_port.c那几千行代码这篇内容应该能帮你省下不少时间。需要提前说明的是下面涉及的寄存器地址、位定义都基于标准的 16550A 兼容 UART不同 SoC 的 8250 变体比如某些集成 UART在寄存器偏移和时钟上会有差异但整体框架是一致的。我会在关键处标注哪些是通用逻辑、哪些需要按你的硬件手册核对。2. 8250 驱动与 16550A 的整体设计思路2.1 为什么 x86 上默认就是 8250 驱动在 x86 体系里传统的串口控制器基本都遵循 8250/16450/16550 这一脉的寄存器模型。8250 是最早的型号16450 加了 16 字节的收发 FIFO 但没做好16550 修正了 FIFO 的 bug16550A 则是真正被广泛使用的版本。Linux 内核里的8250驱动并不是只针对 8250 这一颗芯片而是一个覆盖整个系列的框架通过uart_port和uart_ops把不同变体的差异抽象出来。选择这套框架的原因很实际寄存器布局高度兼容驱动核心逻辑可以复用只需要针对具体芯片补充时钟、寄存器偏移、特殊初始化序列。x86 平台上的8250_pci、8250_pnp都是在这个核心之上做枚举和资源映射。所以你在 x86 上看到的/dev/ttyS*背后几乎都是 8250 驱动在管。2.2 16550A 的寄存器模型一切操作的落脚点要理解TIOCMGET和 RTS必须先知道 16550A 有哪些寄存器。它用 3 根地址线A0-A2选择 8 个寄存器但部分寄存器是复用的靠 LCR 的 DLAB 位切换。核心寄存器如下偏移DLAB0DLAB1说明0RBR读/ THR写DLL接收/发送缓冲或波特率低字节1IERDLM中断使能或波特率高字节2IIR读/ FCR写-中断识别 / FIFO 控制3LCR-线路控制数据位、停止位、校验、DLAB4MCR-调制解调器控制RTS、DTR、OUT1、OUT2、LOOP5LSR-线路状态数据就绪、溢出、错误6MSR-调制解调器状态CTS、DSR、RI、DCD7SCR-暂存寄存器RTS 的控制位就在 MCR 的 bit 1。这一点非常关键RTS 是一个输出信号由 MCR 寄存器直接控制。而TIOCMSET最终要做的就是根据传入的 modem 状态去改写 MCR 的相应位。TIOCMGET则是反过来读 MCR 和 MSR拼出当前的 modem 状态返回给应用层。2.3 分层结构应用层到寄存器之间隔了什么从应用层往下路径大致是这样的应用调用ioctl(fd, TIOCMSET, flags)tty 层tty_ioctl识别命令转给tty_driver的ioctl或tiocmset回调串口核心层serial_core.c的uart_tiocmset处理具体驱动8250的uart_ops-set_mctrl被调用serial8250_set_mctrl读写 MCR 寄存器这条链路里serial_core做了通用封装8250 只负责最后那一步硬件操作。理解这个分层排查问题时就能快速定位到底是应用传参错了、tty 层拦截了还是驱动没实现对应回调。3. TIOCMGET 与 TIOCMSET 的核心细节解析3.1 TIOCMGET 到底返回了什么TIOCMGET返回的是一个整数位掩码每一位对应一个 modem 信号。常见的位定义来自include/uapi/asm-generic/termios.h包括TIOCM_LE线路使能TIOCM_DTR数据终端就绪TIOCM_RTS请求发送TIOCM_ST辅助输出TIOCM_SR辅助输出TIOCM_CTS清除发送TIOCM_CAR载波检测DCDTIOCM_RNG振铃指示TIOCM_DSR数据装置就绪其中 DTR、RTS、OUT1、OUT2 是输出信号由本端控制CTS、DSR、DCD、RI 是输入信号反映对端状态。TIOCMGET会把这两类都读出来拼在一起。8250 的实现里输出部分读 MCR输入部分读 MSR然后做位映射。这里有个容易踩的坑MSR 的输入状态位是粘滞的。也就是说一旦 CTS 或 DCD 发生变化MSR 对应位会被置位并保持直到你读一次 MSR 才清除。所以TIOCMGET读到的输入状态反映的是自上次读取以来是否发生过变化而不是当前瞬时电平。如果你需要精确的实时电平得结合中断或轮询策略来处理。3.2 TIOCMSET 的参数语义TIOCMSET传入的 flags 表示期望的完整 modem 输出状态而不是增量。驱动会用它去覆盖 MCR 中对应的位。8250 的set_mctrl大致逻辑是void serial8250_set_mctrl(struct uart_port *port, unsigned int mctrl) { unsigned char mcr 0; if (mctrl TIOCM_RTS) mcr | UART_MCR_RTS; if (mctrl TIOCM_DTR) mcr | UART_MCR_DTR; if (mctrl TIOCM_OUT1) mcr | UART_MCR_OUT1; if (mctrl TIOCM_OUT2) mcr | UART_MCR_OUT2; if (mctrl TIOCM_LOOP) mcr | UART_MCR_LOOP; serial_out(port, UART_MCR, mcr); }注意这里mcr是从 0 开始重新拼的意味着没有在 mctrl 里置位的输出信号会被清零。所以如果你只想拉高 RTS 而保留 DTR必须把 DTR 也一起传进去否则 DTR 会被拉低。这是新手最常犯的错误之一。3.3 RTS 的两种身份手动控制 vs 硬件流控RTS 在串口里有两个完全不同的角色混淆它们会导致行为异常手动模式应用通过TIOCMSET直接控制 RTS 电平用于自定义的握手协议或方向控制比如 RS485 收发切换。硬件流控模式由驱动自动控制。当接收 FIFO 快满时自动拉高 RTS 通知对端暂停快空时拉低继续。此时应用再调TIOCMSET去改 RTS 是无效的因为驱动会在中断里覆盖你的设置。判断当前处于哪种模式看termios.c_cflag是否设置了CRTSCTS。如果设了RTS 就归驱动管如果没设RTS 才是你能手动控制的。我在调试时就遇到过应用反复设 RTS 但电平纹丝不动的情况最后发现是CRTSCTS被打开了驱动在自动接管。4. 实操过程从应用层到寄存器的完整验证4.1 环境准备与设备确认先确认你的串口设备和驱动。在 x86 上执行dmesg | grep -i ttyS ls -l /dev/ttyS* cat /proc/tty/driver/serial/proc/tty/driver/serial会列出每个串口的类型、端口地址、中断号、当前 modem 状态。如果看到uart:16550A说明驱动识别到了 16550A 兼容芯片。记下端口地址比如0x3f8后面用setpci或devmem验证寄存器时会用到。注意直接操作/dev/mem或devmem需要 root 权限且在某些内核配置下被禁用。生产环境不要这么干仅用于调试验证。4.2 用一段小程序验证 TIOCMGET/TIOCMSET下面这段代码可以直接编译运行用来观察 RTS 和 DTR 的变化#include stdio.h #include fcntl.h #include sys/ioctl.h #include unistd.h #include termios.h int main(int argc, char **argv) { int fd open(argv[1], O_RDWR | O_NOCTTY); if (fd 0) { perror(open); return 1; } int status; ioctl(fd, TIOCMGET, status); printf(初始状态: RTS%d DTR%d CTS%d DSR%d DCD%d\n, !!(status TIOCM_RTS), !!(status TIOCM_DTR), !!(status TIOCM_CTS), !!(status TIOCM_DSR), !!(status TIOCM_CAR)); status | TIOCM_RTS; ioctl(fd, TIOCMSET, status); printf(拉高 RTS 后: 0x%x\n, status); sleep(1); status ~TIOCM_RTS; ioctl(fd, TIOCMSET, status); printf(拉低 RTS 后: 0x%x\n, status); close(fd); return 0; }编译运行gcc -o rts_test rts_test.c sudo ./rts_test /dev/ttyS0如果你有示波器或万用表可以直接量对应引脚的电平变化。没有的话用回环测试把 RTS 和 CTS 短接拉高 RTS 后TIOCMGET应该能看到 CTS 也变高。这是验证链路是否打通的最快方法。4.3 参数计算波特率与分频值虽然本文重点是 modem 控制但波特率配置是串口绕不开的一环顺带说清楚。16550A 的波特率由 DLL/DLM 组成的分频值决定分频值 输入时钟 / (16 × 波特率)假设输入时钟是 1.8432 MHz要 9600 波特率分频值 1843200 / (16 × 9600) 12所以 DLL12DLM0。如果算出来不是整数就会有波特率误差。误差超过 2% 左右通信就可能出错。这也是为什么有些非标准波特率在特定时钟下会不稳定——分频值取整带来的偏差累积了。在 8250 驱动里这个计算由serial8250_get_divisor完成它会尽量选误差最小的分频值。你可以在dmesg里看到驱动报告的时钟频率用来反推实际波特率。4.4 硬件流控的启用与验证启用 RTS/CTS 硬件流控struct termios tio; tcgetattr(fd, tio); tio.c_cflag | CRTSCTS; tcsetattr(fd, TCSANOW, tio);启用后RTS 由驱动自动控制。验证方法是让对端持续发送数据但不读取当接收 FIFO 达到触发阈值通常是 8 或 14 字节取决于 FCR 配置RTS 应该自动拉高。你可以用TIOCMGET轮询观察或者直接量引脚。实操心得FCR 的触发阈值会影响流控的灵敏度。阈值设太低比如 1 字节会导致 RTS 频繁翻转增加对端负担设太高比如 14 字节则留给对端的反应时间太短容易溢出。我一般用 8 字节作为折中实测在 115200 波特率下比较稳。5. 常见问题与排查技巧实录5.1 问题速查表现象可能原因排查方向TIOCMSET 后 RTS 无变化CRTSCTS 已启用驱动接管检查 c_cflag关闭硬件流控TIOCMGET 的 CTS 一直是高MSR 粘滞位未清除读一次 MSR 或重新打开设备DTR 被意外拉低TIOCMSET 传参未包含 DTR传入完整状态而非只置 RTS波特率不准分频值取整误差大核对输入时钟换标准波特率收数据丢包FIFO 溢出流控未生效检查 FCR 阈值和 CRTSCTSioctl 返回 ENOTTY设备不是 tty 或驱动未实现确认设备节点和驱动加载5.2 几个我踩过的坑坑一以为 TIOCMSET 是增量操作。实际上它是全量覆盖。我第一次写代码时只status | TIOCM_RTS但status是从TIOCMGET读来的包含了 DTR所以没出问题。后来我图省事直接传了个只含 RTS 的值结果 DTR 被拉低对端设备直接掉线。这个教训让我养成了先 GET 再改再 SET的习惯。坑二忽略 MSR 的粘滞特性。我在做 DCD 检测时发现TIOCMGET一直报告 DCD 有效但实际线路早就断了。原因是 MSR 的 DCD 变化位没被清除。解决办法是每次判断前先读一次 MSR或者干脆用TIOCMIWAIT等待边沿变化而不是轮询状态位。坑三硬件流控和手动 RTS 混用。有个项目需要在正常通信时用硬件流控但在特定阶段手动控制 RTS 做方向切换。我一开始没关CRTSCTS就去TIOCMSET结果驱动和我的代码互相打架RTS 电平乱跳。正确做法是切换阶段时先tcsetattr关掉CRTSCTS手动控制完再打开。坑四没确认芯片是不是真的 16550A。有些廉价 USB 转串口芯片号称兼容 16550A但 FIFO 行为不一致流控阈值设了不生效。用cat /proc/tty/driver/serial看类型如果显示uart:unknown或8250就要小心了可能需要专门的驱动或调整参数。5.3 调试工具与手段除了前面提到的ioctl小程序还有几个手段值得掌握stty -F /dev/ttyS0 -a查看当前 termios 配置确认crtscts是否启用。cat /proc/tty/driver/serial看驱动报告的端口状态和 modem 位。setserial /dev/ttyS0老牌工具能看端口类型和配置部分发行版需要单独安装。逻辑分析仪抓 RTS/CTS/TXD 的时序是验证流控行为最直接的方式。没有的话用回环短接也能验证大半。提示调试 modem 控制时建议先把波特率降到 9600 或更低减少时序干扰确认逻辑正确后再提速。6. 从驱动源码看 set_mctrl 的完整调用链6.1 serial_core 层的封装应用调ioctl(fd, TIOCMSET, flags)后tty 层会走到uart_tiocmset在serial_core.cstatic int uart_tiocmset(struct tty_struct *tty, unsigned int set, unsigned int clear) { struct uart_state *state tty-driver_data; struct uart_port *port state-uart_port; unsigned int mctrl; mutex_lock(port-mutex); mctrl port-mctrl; mctrl ~clear; mctrl | set; port-ops-set_mctrl(port, mctrl); port-mctrl mctrl; mutex_unlock(port-mutex); return 0; }注意这里维护了一个port-mctrl软件缓存。TIOCMSET的 set/clear 参数会先作用到这个缓存再整体下发给硬件。这个设计的好处是驱动不用每次都读寄存器也避免了读写竞争。但这也意味着软件缓存和硬件实际状态可能不一致——如果硬件因为流控自动改了 RTS缓存里还是旧值。所以排查时不能只信缓存。6.2 8250 的 set_mctrl 实现8250 的set_mctrl就是前面展示的serial8250_set_mctrl。它把mctrl映射到 MCR 位然后serial_out写寄存器。serial_out会根据端口类型选择outb、mmio或iomem访问方式这也是 8250 框架能同时支持 x86 IO 端口和 ARM MMIO 的原因。6.3 硬件流控的自动控制路径当CRTSCTS启用时RTS 的自动控制发生在接收中断处理里。serial8250_rx_chars读数据后会检查 FIFO 剩余空间调用serial8250_set_mctrl去调整 RTS。具体阈值由port-fifosize和 FCR 配置决定。这条路径和应用层的TIOCMSET是并行的所以两者同时操作 RTS 必然冲突。理解这一点后前面提到的坑三就有了理论解释不是驱动有 bug而是两个控制源在设计上就不该同时活跃。7. 影响范围与延伸思考8250 驱动虽然老但它的影响范围远超很多人想象。x86 服务器上的串口控制台、工业现场的 RS485 转换、GPS 模块对接、甚至一些调试探针底层都跑在这套框架上。TIOCMGET/TIOCMSET这套接口从早期 Unix 延续至今兼容性极好但语义上的细节全量覆盖、MSR 粘滞、流控冲突也继承了下来。如果你在做 RS485 方向控制典型做法就是用TIOCMSET手动控制 RTS在发送前拉高、发送完拉低。但要注意发送完成的判断——不能写完就立刻拉低得等 LSR 的 TEMT 位发送器空置位否则最后一个字节可能被截断。这个细节我在实际项目里调了很久才稳定。另外现代内核里 8250 还有8250_dw、8250_exar等一堆变体驱动它们复用核心逻辑但各有特殊处理。如果你用的不是标准 x86 串口建议先确认具体是哪个变体再对照它的set_mctrl实现因为有些芯片的 RTS 控制位不在 MCR 里而是通过 GPIO 或专用寄存器。最后分享一个我常用的验证套路写一个回环测试程序把 RTS 和 CTS 短接、TXD 和 RXD 短接然后跑一遍拉 RTS → 读 CTS → 发数据 → 收数据的完整流程。这个测试能一次性覆盖 modem 控制、流控、收发三条链路比单独测某一项高效得多。跑通之后再接真实设备心里就有底了。

相关新闻

Codex 说任务完成之前,还缺哪一格?用验收证据矩阵找空白

Codex 说任务完成之前,还缺哪一格?用验收证据矩阵找空白

Codex 说任务完成之前,还缺哪一格?用验收证据矩阵找空白 本文围绕“验收证据矩阵”设计一个可离线复核的教学场景:不调用在线模型、不连接设备、不上传业务数据。核验日期为 2026-10-14。 一、先定义本题真正要避免的错误 一个通过的测试不能覆盖配置、迁移、视觉检查或外部…

2026/10/14 15:40:36 阅读更多 →
QOwnNotes 脚本钩子(Hooks)完全指南:从笔记生命周期到编辑器高亮的 22 个扩展点

QOwnNotes 脚本钩子(Hooks)完全指南:从笔记生命周期到编辑器高亮的 22 个扩展点

桌面应用 【免费下载链接】QOwnNotes QOwnNotes is a plain-text file notepad and todo-list manager with Markdown support and Nextcloud / ownCloud integration. 项目地址: https://gitcode.com/gh_mirrors/qo/QOwnNotes 点击查看 免费下载 本篇技术指南系统…

2026/10/14 15:40:36 阅读更多 →
Python PyQt6金价监控气泡工具开发实战

Python PyQt6金价监控气泡工具开发实战

简介:这是一款面向Windows桌面用户的轻量级金价监控小工具,专为关注黄金价格变动的投资者、理财爱好者及日常需要快速查看金价的办公人群设计,解决手动刷新网页或切换小程序获取实时金价的繁琐问题。资源包共2个文件,含1个Python源…

2026/10/14 15:40:36 阅读更多 →

最新新闻

Linux下Modbus TCP服务端实战:寄存器规划与数据采集指南

Linux下Modbus TCP服务端实战:寄存器规划与数据采集指南

简介:基于Linux平台的TCPModbus服务端实现,面向工业自动化开发人员、嵌入式工程师及Modbus协议学习者,用于解决各类工业设备通过TCP/IP网络与上位机或PLC进行数据通信的需求。服务端覆盖输入寄存器(0x04)、离散输入&am…

2026/10/14 16:24:36 阅读更多 →
Linux 下用 nvm 升级 Node.js 到指定版本:安装、切换与回滚全指南

Linux 下用 nvm 升级 Node.js 到指定版本:安装、切换与回滚全指南

前阵子帮人处理一台 Linux 服务器,对方想跑一个依赖 Node.js 新特性的工具,结果node -v打出来还是 18.x。按老思路,要么用系统包管理器升级,要么去官网下二进制包直接替换,可那是台带着线上服务的机器,谁也…

2026/10/14 16:24:36 阅读更多 →
短视频虚假宣传判定标准更新,带货博主内容合规要点梳理

短视频虚假宣传判定标准更新,带货博主内容合规要点梳理

短视频带货是直播电商自媒体很常用的变现方式,创作者靠着短视频介绍商品,引导消费者下单购买。现在带货类的内容数量越来越多,平台更新了短视频虚假宣传的判定标准,不少带货博主都在翻看这份新规,不想让自己的账号受到…

2026/10/14 16:24:36 阅读更多 →
光芯片太火,连卖百货的都坐不住了

光芯片太火,连卖百货的都坐不住了

导语:东百集团准备拿出3.16亿元跨界“追光”。一家做了多年百货、购物中心和仓储物流生意的上市公司,突然决定去买光芯片。10月11日晚,东百集团披露,公司全资子公司东百创智拟以3.16亿元,收购杭州快灵光电科技有限公司…

2026/10/14 16:24:36 阅读更多 →
影策3D导演台教程:生成前先摆场走位运镜,短剧镜头规划神器

影策3D导演台教程:生成前先摆场走位运镜,短剧镜头规划神器

人工智能AI 应用媒体生成音视频工作流自动化后端前端 【免费下载链接】open-ai-canvas 【影策】面向 AI 影视创作的开源无限画布工作台,集成多模态生成、分镜编排、素材管理与 Agent 工作流。 项目地址: https://gitcode.com/gh_mirrors/op/open-ai-canv…

2026/10/14 16:24:36 阅读更多 →
[特殊字符] AI学会绕锁!小白程序员必看:网络安全新挑战与收藏指南

[特殊字符] AI学会绕锁!小白程序员必看:网络安全新挑战与收藏指南

🔒 AI学会绕锁!小白程序员必看:网络安全新挑战与收藏指南 本文探讨了AI模型Claude Haiku 4.5在测试中绕过禁令,提交虚假警情至费城警方的案例。文章分析了模型未违规的原因,即禁令中缺少“不许提交表单”的规定。Anth…

2026/10/14 16:23:35 阅读更多 →

日新闻

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/13 16:22:04 阅读更多 →
影刀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 阅读更多 →