news 2026/9/27 2:42:25

RK3576 I3C实战:从I2C迁移到I3C的DTS配置与避坑指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
RK3576 I3C实战:从I2C迁移到I3C的DTS配置与避坑指南

I3C 比 I2C 快 10 倍这个说法,这几年几乎跟着每一颗新 SoC 的发布都会被翻出来聊一遍。我最近在 RK3576 平台上做了一轮总线迁移,把原本挂在 I2C 上的两颗温度传感器和一个触摸屏控制器逐步挪到 I3C 上,顺手把设备树从 I2C 节点改成了 I3C 节点。整个过程走下来,最直观的感受是:接口很快是真的,但很多人只记住了“快 10 倍”这个结论,却忽略了 I3C 在协议层、DTS 配置层和信号完整性上带来的完全不同的约束。这篇文章就把我实测的接口特性、DTS 配置方法,以及那些文档里不会写的坑,一次说清楚。适合正准备评估 I3C 选型、或者已经在 RK3576 上要做这项改动的人参考。

1. 把“快 10 倍”放到速率表里看:结论成立,但口径很重要

1.1 I2C 真正常用的速率,其实连 1MHz 都少见

I2C 协议标准里确实有高速模式(Hs-mode)3.4MHz,但绝大多数嵌入式系统跑的还是 100kHz 标准模式和 400kHz 快速模式。Fast Mode Plus 的 1MHz 都算比较激进的配置了,很多现成传感器模组在原厂参考驱动里给的默认时序还是 400kHz。真正敢一路开到 3.4MHz 的项目,通常会要求非常短的总线长度、极小的上拉电阻和严格控制的 I/O 电容,这在工程上其实是少数场景。

I3C 这边,光最基本的 SDR 单数据速率模式就有 12.5MHz。如果你拿 I2C 快速模式 400kHz 跟 I3C SDR 12.5MHz 去比,倍数直接到了 30 倍以上。这也是网上说“快 10 倍”的底气来源之一。但严谨一点讲,协议标准里 I3C 还有 HDR-DDR、HDR-TSP、HDR-TSL 这些更高阶模式,DDR 模式下时钟 12.5MHz、数据在两个边沿都采样,等效数据率可以到 25MHz 甚至更高。所以“快 10 倍”不是吹牛,但它是一个简化的表达,真正要说准确,必须明确比较的是哪一档对哪一档。

1.2 为什么 I3C 能把时钟拉上去:推挽驱动是核心

I2C 从诞生起就是开漏结构,设备只能把总线拉低,释放后靠外部上拉电阻把电平带回去。开漏的好处是天然支持线与逻辑和多设备仲裁,坏处也很实在:电平上升沿依赖于 RC 充电。总线上挂三五个设备、走线稍微长一点,等效电容就到了几十甚至上百 pF,400kHz 下要让边沿足够陡,上拉电阻已经要压到 1k 到 2.2k 这个区间,功耗和信号质量都要付出代价。

I3C 在 SDR 模式下把 SCL 和 SDA 都改成了推挽驱动,主动输出高电平,不再依赖上拉电阻去“拉”起来。这就解决了高频下上升沿太慢的基础矛盾。DDR 模式更是直接在时钟的两个边沿都采样数据,等效带宽又翻了一倍。代价也很明显,推挽驱动下多个设备同时驱动的碰撞控制只能靠协议层解决,不能再像 I2C 那样靠物理线与去兜底,所以 I3C 控制器内部的时序状态机、CCC 命令队列和总线仲裁逻辑,比 I2C 控制器复杂得多。

1.3 不同对比口径下的真实倍数

我习惯把常用对比口径列成一张表,评估项目时直接查,比背“快 10 倍”有用:

比较对象I2C 速率I3C 速率倍数
标准模式对 SDR100kHz12.5MHz125 倍
快速模式对 SDR400kHz12.5MHz31 倍
Fast Mode Plus 对 SDR1MHz12.5MHz12.5 倍
Hs-mode 对 SDR3.4MHz12.5MHz3.7 倍
Hs-mode 对 HDR-DDR3.4MHz25MHz7.4 倍

所以“快 10 倍”这个说法放在 HDR-DDR 对 Hs-mode 的对比口径下,是站得住脚的,但更常见的真实工程环境是 400kHz 对 SDR,实际能拿到的收益远超 10 倍。反过来说,如果你在一条 I3C 总线上挂了不支持 I3C 的老 I2C 设备,控制器会把总线切到 I2C fallback 模式跟那台设备通信,这段交互的速率会被打回 400kHz 甚至更低。这一点在方案评估阶段就要想清楚,否则容易产生“明明上了 I3C,怎么感觉还是慢”的错觉。

2. RK3576 的 I3C 资源:控制器、时钟树和选型判断

2.1 RK3576 片上 I3C 控制器:先看 dtsi,别盲目抄 RK3588

RK3576 作为瑞芯微 2024 年后的中高端平台,I3C 已经成了标配外设。我这边使用的 BSP 源码里,RK3576 的 dtsi 中 i3c 控制器的数量和编号与 RK3588 不完全一样,这一点必须强调:网上一搜能搜到大量 RK3588 的 I3C DTS 片段,直接往 RK3576 上套很危险,因为中断号、基址、时钟名、复位名都可能不同。

以我看到的 RK3576 设备树为例,控制器节点通常长这样(具体基址和中断号以你手里的 TRM 为准,不同批次 BSP 也有差异):

i3c0: i3c@fead0000 { compatible = "rockchip,i3c"; reg = <0x0 0xfead0000 0x0 0x1000>; interrupts = <GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH>; clocks = <&cru CLK_X3C0>, <&cru PCLK_X3C0>; clock-names = "x3c", "pclk"; resets = <&cru SRST_R_X3C0>; reset-names = "x3c"; pinctrl-names = "default"; pinctrl-0 = <&i3c0_scl>, <&i3c0_sda>; status = "disabled"; };

有些内核版本里 compatible 写的是snps,dw-i3c-master,这取决于供应商把 Synopsys DesignWare I3C 控制器驱动编到哪个框架下。判断自己该用哪种 compatible,最靠谱的办法不是翻文档,而是看 BSP 自带的arch/arm64/boot/dts/rockchip/rk3576.dtsi里有没有现成的 i3c 节点。有就说明供应商已经把它接入 Linux I3C subsystem 了;没有就要确认内核是否打开了CONFIG_I3C和对应 master 驱动,否则就算你在自己的 dts 里编了一大段节点,内核也不认识。

2.2 引脚复用和 I2C 的关系:同一组脚,别同时点亮两个节点

RK3576 的 I3C 控制器引脚并不是凭空多出来的,很多情况下它和 I2C 的某个控制器共用同一组 IO 的 mux 选项。也就是说,你在 dts 里开启&i3c0的同时,不能再把对应引脚的&i2c0(举例)也设为status = "okay"。否则 pinctrl 子系统在解析时会发现同一组引脚被两个节点申请,轻则警告,重则两个控制器互相干扰,总线上出现无法解释的超时。

我踩过一次类似的坑:I3C 节点和 I2C 节点分别放在了两个不同的设备树 include 文件里,板级 dts 同时&i3c0 {}和&i2c0 {}都没删干净,结果启动后 I3C 设备 probe 成功,但第一次 DAA 动态地址分配就超时。后来查 pinctrl 状态才发现引脚被 I2C 节点占用。所以每次切总线方案时,都要全局搜一下项目 dts 里还有没有同组引脚的 I2C 节点遗留。

另外,引脚复用配置本身也要注意。I3C 高速模式下建议优先选择专门的 I3C 功能复用,而不是 I2C 功能复用。有些 BSP 的 pinctrl 节点只提供了i3c0_x3c这组复用,数据手册上写的是 x3c 这个名字,别因为在 dtsi 里搜 “i3c” 搜不到就放弃,多看一眼寄存器手册的复用表格。

2.3 时钟树和电源域:只配了节点还不够

I3C 控制器通常有两个时钟:一个是操作总线的功能时钟(比如x3c),一个是访问控制器寄存器的外设时钟(比如pclk)。这两个时钟在 dtsi 的clocks属性里都会列出来。有些同学只开CLK_X3C0而忽略了PCLK_X3C0,启动时会发现控制器寄存器可以读,但一发起传输就卡住——因为寄存器访问是通过 pclk 做的,pclk 没开,外设寄存器访问路径并不可靠。

这在 RK3576 上尤其要注意。它不像小芯片那样把所有外设都放在同一个简单时钟域里,I3C 控制器可能挂在特定 power domain。如果控制器所在电源域在系统 suspend/resume 流程里被关掉了,而 dts 里又没有描述清楚依赖关系,就会出现唤醒后 I3C 设备还在,但总线彻底罢工的现象。经验做法是:第一版 dts 就复制供应商评估板上的电源域配置,不要自己凭感觉去掉power-domains属性。

3. DTS 从 I2C 改成 I3C:节点抄法、reg 三 cell 和子设备挂载

3.1 最稳的起步方式:从 dtsi 里拿现成框架,再做增量修改

很多第一次写 I3C DTS 的人,会习惯性打开 I2C 的节点模板,然后把 compatible 改一改。这个思路在 I2C 上没问题,但 I3C 节点的地址 cell 数量和子设备表述方式都不同,硬套容易出错。I3C 总线的控制器节点一般要这样定义:

i3c0: i3c@fead0000 { compatible = "rockchip,i3c"; #address-cells = <3>; #size-cells = <0>; /* 其余属性沿用 dtsi 里的默认值 */ };

#address-cells = <3>和 I2C 的<1>是完全不一样的,因为 I3C 子设备节点需要表达动态地址、偏好静态地址和属性信息。对内核的 I3C 核心来说,这 3 个 cell 是有明确语义的,不能省,也不能为了省事把别人设备树里的<1>抄过来。

改完控制器节点后,再在板级 dts 里像&i2c0那样去引用它:

&i3c0 { status = "okay"; pinctrl-names = "default"; pinctrl-0 = <&i3c0_scl>, &i3c0_sda>; /* 速率参数,名称以你的 BSP 内核版本为准 */ i3c-sdr-hz = <12000000>; i3c-ddr-hz = <24000000>; };

i3c-sdr-hz和i3c-ddr-hz这类属性在个别内核版本里不一定是这个命名,所以我建议你拿到源码后先看一眼Documentation/devicetree/bindings/i3c/i3c.txt或者对应 vendor 的 yaml 绑定文档。重要的是理解逻辑:SDR 是基础模式,DDR 是增强模式,如果外设只支持 SDR,DDR 设再高也不会被用到。

3.2 reg 三 cell 的坑:动态地址、偏好静态地址和标志位

I3C 子设备节点的 reg 写法,是和我之前 I2C 经验差距最大的地方。I2C 子设备写reg = <0x48>,就是固定的 7bit 从地址;I3C 则允许控制器在 DAA 流程里给设备分配一个全新的动态地址。所以 reg 的三个 cell 分别表示:

  • 第一个 cell:动态地址,如果为 0,表示由控制器在枚举时分配;
  • 第二个 cell:偏好静态地址,设备上电后如果没被分配动态地址,会先尝试用这个地址通信;
  • 第三个 cell:标志位,用来表达设备是否支持 IBI、是否要求加入时的特殊处理等。

一个典型子设备节点是这样写的:

&i3c0 { // ... tmp117: temperature-sensor@0 { compatible = "ti,tmp117-i3c"; reg = <0x0 0x48 0x0>; }; };

写这段的时候,temperature-sensor@0只是一个方便阅读的标签,真正决定访问路径的是 reg 三 cell。如果第二个偏好静态地址 0x48 与总线上另外一个设备的静态地址冲突,DAA 会避开冲突并重新分配。所以千万别把这里的第二个 cell 当成 I2C 那样“写死地址”去理解,它只是一个偏好,不是最终动态地址。

如果你只是临时验证某颗 I3C 设备,也可以把三个 cell 都写成 0,完全走动态地址流程。但要注意,有些老老外设虽然物理上支持 I3C,驱动里却没实现 DAA 相关的回调,这时候强制动态分配会导致设备无法正常枚举。稳妥的做法是先用 0x0 动态地址跑一次,如果 dmesg 里出现 DAA 超时,再把偏好静态地址填上试试。

3.3 挂载不支持 I3C 的老 I2C 设备:I2C fallback 的正确姿势

很多项目并不是所有外设都换成了 I3C 版本。随便举几个:可能触摸屏已经是 I3C 原生设备,但旁边还有一颗只支持 I2C 的 eeprom 或老款环境传感器。此时不需要给这些老设备写什么特殊节点,你可以在&i3c0内直接挂一个普通 I2C 风格子节点:

&i3c0 { at24c02: eeprom@50 { compatible = "at24,24c02"; reg = <0x50>; pagesize = <8>; size = <256>; }; };

内核的 I3C 总线驱动会检测到这个设备不支持 I3C DAA,自动把控制器切换到 I2C fallback 模式去访问它。这里有个细节很多人不知道:一条 I3C 总线上只要存在需要 fallback 的老设备,这部分通信速率就会明显低于 I3C 原生设备;Linux 的 i3c core 对 fallback 设备有独立的时序约束参数,你设置的i3c-sdr-hz不会作用到它身上。所以评估性能时,不能把所有设备都按 12.5MHz 的乐观预期去算。

另外,I2C fallback 模式下,总线上的动态地址分配、IBI 等 I3C 特性对该老设备完全失效。这类设备的中断如果之前是通过独立 GPIO 上报的,可以继续保留 GPIO 中断方案,不用为了“统一”而强行改造。

4. 速率之外的变化:CCC 命令、IBI 中断和 Linux 驱动模型

4.1 CCC 命令是总线的“管理层”,不是普通读写

I3C 相比 I2C 最本质的变化,不是频率,而是协议里多了一种叫 CCC(Common Command Code)的命令体系。CCC 有广播和定向两种类型,用来做动态地址分配、设备使能/禁用、模式切换、总线重置、热加入协商等管理操作。你写驱动时不会直接操作这些,但控制器固件和内核 I3C 子系统的交互大量依赖它。

举例来说,I3C 控制器上电后的第一个动作就是发送 RSTDAA 或 SETDASA,然后再进入 DAA 流程逐个枚举总线上的设备。这个角色等同于“总线的 DHCP 服务器”,和 I2C 里从设备地址焊死在芯片里的逻辑完全不同。如果你用逻辑分析仪抓 I3C 总线,看到的第一个有内容的时序往往不是某个传感器的数据帧,而是一连串 CCC 帧,这是在分配动态地址。

在 DTS 层面,CCC 相关的东西你不需要显式配置,但理解它很有意思:为什么 I3C 设备节点 reg 是三个 cell?就是因为这个设备最终地址是由 DAA 动态确定的,偏好静态地址只是“建议值”。控制器发送 SETDASA 时,会把建议地址写进设备,如果设备支持,就会采用;后续就不再依靠地址竞态了。

4.2 IBI 代替 GPIO 中断:省线,但要做好驱动层适配

I3C 的另一个核心特性是 In-Band Interrupt,即带内中断。I2C 时代,传感器产生中断只能拉一根 GPIO 去通知 SoC;I3C 时代,从设备可以直接在总线上发起一个 IBI Request,控制器在总线空闲时仲裁这个请求并响应。好处显而易见:省掉一根 GPIO,BOM 降低,原理图连线也干净。

但带内中断也有代价。第一,IBI 请求的时序优先权和普通数据传输不同,控制器内部的仲裁逻辑如果优先级配得不好,高频率的中断事件可能会让正常数据流变得卡顿。第二,驱动模型里多了一个i3c_ibis或等价的事件处理路径,你从设备的 driver 不能再简单依赖传统 IRQ 号触发中断回调,而是要注册一套和 I3C master 关联的事件处理接口。

RK3576 的控制器对 IBI 的支持在 BSP 里已经比较完整,但我建议项目前期不要把所有传感器都换成 IBI,先用一个设备把 IBI 链路验证通,确认中断频率和数据吞吐量的关系,再决定是否批量迁移。尤其是触摸屏这种中断频率不低的外设,如果 IBI 处理路径里还有额外的软件调度开销,性能不一定比独立 GPIO 中断好。

4.3 Linux 侧驱动模型:I3C 不是“I2C 的改名版”

在 Linux 内核里,I2C 和 I3C 各自有独立的子系统。I2C 是i2c-core,设备模型用struct i2c_client;I3C 是i3c-core,设备模型有struct i3c_device。你在写驱动时不能把i2c_driver直接拿去匹配 I3C 设备,必须用i3c_driver和i3c_device_id结构。老 I2C 设备走 fallback 模式则例外,它的驱动仍然是i2c_driver,匹配方式也更接近传统 I2C。

实际开发里,很多传感器厂商给的 Linux 驱动只写了 I2C 版本。想快速在 I3C 总线上用起来,有两条路:

  • 稳妥路线:把该设备当作老 I2C 设备挂在&i3c0下,驱动一点不用改,但享受不到高速和 IBI。
  • 完整路线:自己基于i3c_driver写一个小驱动,通常是把原 I2C 的读写函数改成i3c_device_do_priv_xfers或对应的 regmap 封装。

以我的经验,如果设备本身有明确的高吞吐需求(比如高分辨率触摸屏、多通道传感器聚合),值得走第二条路;如果只是普通温湿度传感器,I2C fallback 足够用了,过度设计没意义。

内核里还要记得开CONFIG_I3C、CONFIG_I3C_MASTER。你会得到类似/dev/i3c-0的总线设备节点。用户态工具i3c-tools(可从开源仓库拉取)可以用来枚举总线设备、查看动态地址和 PID,调试阶段非常有用,后面我还会聊到具体用法。

5. 实测踩坑记录:信号完整性、dmesg 报错与逻辑分析仪验证

5.1 信号完整性比 I2C 敏感得多:上拉电阻和板级寄生电容

I3C 的高速是建立在推挽驱动基础上的,但它仍有开漏窗口期,特别是 SDR 模式下做总线仲裁和 STOP/START 条件时,总线上拉能力依然要够。在 RK3576 实际板子上,如果沿用 I2C 时代的 4.7k 上拉电阻,12.5MHz 下很容易出现上升沿不达标,导致设备偶发失步。这个问题的典型现象是:系统刚启动几百次里正常,偶尔在某个设备的连续读取中报一次 CRC 错误。

解决方向不是简单粗暴地减小电阻——太小的上拉电阻会让 SDA 低电平抬不干净,反而更糟。正确的做法是参考目标设备的 I3C 时序要求,计算总线上拉电阻的上下限。一般 I3C 设备手册里会给最小上升时间和最大上升时间,实际板子可以用如下公式估算:

  • 总线电容 Cbus = 设备引脚电容之和 + 走线寄生电容;
  • 上拉电阻上限约等于 tR / (0.8473 × Cbus),其中 tR 是设备要求的最大上升时间;
  • 上拉电阻下限取决于 VOL max 和推挽电流,公式是 (Vcc - VOL_max) / IOL_max。

这里的边界不需要算到完全精确,但至少要知道:不是电阻越小越好,也不是电阻越大越稳,它在一个窗口区间内。

RK BSP 里有些 I3C 节点会带上 read-puller 这类边沿控制参数,用来调整控制器接收端的采样点。调速率时如果硬件上拉电阻已经确定了,优先检查这个参数是否和实际板级匹配。我这边第一次把 SDR 提到 12.5MHz 后出现随机超时,后来就是拿逻辑分析仪测出边沿余量不足,最后一边微调上拉电阻、一边调整 read-puller 才稳定下来。

5.2 常见 dmesg 报错与排查顺序

症状根因排查方向
i3c0: timeout waiting for target response设备未进入 I3C 模式或上拉不足用逻辑分析仪看总线是否有 ACK/NACK、测边沿
DAA failed子设备 reg 三 cell 配置错误,或设备不支持 DAA检查 reg 的第一个 cell,尝试偏好静态地址
设备注册成功但读写全返回错误SDR 速率设置过高,设备只能跑低速率降低i3c-sdr-hz,确认设备手册最高速率
I3C 和 I2C 节点同时使用后死锁引脚复用冲突全局搜索 dts 里同引脚的 I2C 节点并禁用
唤醒后总线卡住电源域或时钟在 suspend 时被关掉确认 power-domains 配置是否与供应商参考板一致

排查时不要一上来就怀疑硬件。第一步先用i3c dump或dmesg | grep i3c看控制器是否完成了枚举。如果枚举通过了,问题大概率出在时序或外设驱动上;如果枚举都没过,方向应该是 DTS、电源、引脚复用和信号完整性。

i3c-tools的典型操作是:

# 查看所有 I3C 总线 ls /dev/i3c-* # 导出总线信息 i3c dump /dev/i3c-0

如果你用的是供应商深度改过的 BSP,工具不一定直接可用,但内核里那些i3c_*debugfs 节点多少也能顶一下。逻辑分析仪才是最终仲裁者。

5.3 逻辑分析仪怎么看 I3C:先分清 I2C 兼容帧和 SDR 帧

I2C 分析仪默认只能解 I2C 协议,拿来抓 I3C 信号会一脸懵。I3C 总线上有几种帧:带 ST 条件的 I2C 兼容帧、带 SDR 帧头的新帧、CCC 帧等。它们的起始条件、重复起始条件和 STOP 条件的定义与 I2C 有微妙的差异,普通逻辑分析仪很容易把 I3C 的 DAA 流程误判成“Bus error”。

我建议你用支持 I3C 解码的逻辑分析仪方案,或者至少手动把采样率调到 100MHz 以上,先抓一段只有琥珀色(?)总线的枚举片段,人工对比协议规范中的 I3C 帧结构,确认自己能分辨 Start、Repeated Start、STOP、CCC、Dynamic Address 这些关键时段后,再挂真实设备,否则排错效率会非常低。

上次我把 RK3576 的 I3C 节点改成支持两颗传感器和一个 fallback eeprom 后,抓到的波形里三种帧混在一起。用 I2C 模式分析仪看,几乎所有包都报 CRC 错;切换到 I3C 解码思路后,一眼就看出是 fallback I2C 设备的地址周期占用了总线,影响了后续 I3C 设备的一笔 SDR 传输。这类问题不抓波形,靠猜是猜不出来的。

5.4 什么时候别急着上 I3C:几个判断依据

I3C 优点多,但它不是万能药。我见过不少项目本来 I2C 用得挺好,看了“快 10 倍”的宣传就直接上 I3C,结果给自己添了一堆事。这里有几个我实际判断时的依据,供参考:

  • 总线上都是老 I2C 设备,只有一两个网卡 EEPROM 之类的小容量存储设备:I2C fallback 模式下,I3C 原生设备数量太少,高速优势发挥不出来,不如维持原来的 I2C 总线。
  • 板子走线特别长,总电容明显超标:I3C 高速工作对走线长度和 PCB 布局有更高要求,不适合随便拉飞线。
  • Linux 内核版本太老:早期内核 I3C 子系统还不够完善,Rockchip 的 BSP 打补丁也不一定齐全。如果内核版本低于某个成熟度,整个 I3C 驱动栈可能处于实验状态,调试成本很高。
  • 团队对 I3C 协议不熟,也没有支持 I3C 解码的逻辑分析仪:高速协议调试本质上就是“看波形、摸协议”,没有趁手工具会非常痛苦。

如果以上四条都不沾,那 I3C 确实值得上。RK3576 上 I3C 带来的是带宽红利和 GPIO 节省,在传感器数量一多、I2C 中断引脚吃紧的项目里,收益非常直接。

最后说个自己的体会。这次迁移我花了最多时间的地方,不是 DTS 的语法,而是从逻辑分析仪上分辨“这是 SDR 帧还是 I2C 兼容帧”。I3C 的起始条件、重复起始、STOP 条件跟 I2C 有细微差别,只看波形不看 CCC 命令结构,很容易把一段合法的 DAA 当成总线错误。你要是也准备上手,建议先把逻辑分析仪采样率提上去,先分析一条只有 CCC 命令的总线,再挂真实设备,会比对着寄存器一遍遍猜快很多。毕竟 RK3576 上 I3C 的潜力很大,但能不能发挥出来,就看最初这两步验证打得够不够扎实。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/27 2:36:49

零基础学C语言:从语法到指针的完整路线与避坑指南

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

作者头像 李华
网站建设 2026/9/27 2:33:53

立创EDA安装全攻略:专业版与标准版选型及避坑指南

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

作者头像 李华
网站建设 2026/9/27 2:33:38

AI正在悄悄淘汰律师职业,但会用它的人反而涨薪了

过去一年半&#xff0c;我眼看着 Codex 这类编程 Agent 把我们行业的”初级活”吃掉了一大块&#xff1a;写单测、改样板代码、查日志、搭数据管道&#xff0c;以前要带一个应届生干两周的事&#xff0c;现在一个中级工程师开几个并行任务&#xff0c;一下午收工。组里没人被裁…

作者头像 李华
网站建设 2026/9/27 2:29:03

数学建模2003年D题露天矿卡车调度:整数规划与Python求解实战

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

作者头像 李华
网站建设 2026/9/27 2:25:24

查重合格但AI率超标,有哪些免费工具能帮助降低论文AI率?

查重合格但AI率超标&#xff0c;有哪些免费工具能帮助降低论文AI率&#xff1f; 重复率已经符合学校要求&#xff0c;AIGC检测却没通过。最担心的是重新改全文后&#xff0c;AI率没有明显下降&#xff0c;原本合格的重复率还升上去了。这时应保留查重合格的底稿&#xff0c;针…

作者头像 李华