news 2026/9/13 17:02:51

LabVIEW UDS上位机从TOOMOSS到ZLG的CAN硬件移植指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
LabVIEW UDS上位机从TOOMOSS到ZLG的CAN硬件移植指南

1. 项目概述:为什么一个CAN UDS上位机的移植值得专门写十三篇?

“基于周立功的CAN UDS升级上位机-LabVIEW版本(十三):从图莫斯到ZLG的移植指南”——这个标题里藏着三个关键信号:CAN总线UDS诊断协议LabVIEW上位机开发,而“十三”这个数字不是凑数,它真实反映了工业现场设备固件升级工具链演进的复杂度。我做汽车电子和工业控制器诊断工具开发快十年了,亲手写过C#、Python、LabVIEW三套UDS刷写上位机,也帮客户把十几套老旧LabVIEW程序从TOOMOSS CAN卡迁移到ZLG系列。所谓“移植”,绝不是换个驱动、改个DLL路径那么简单。它是一次对底层通信时序、协议栈容错机制、硬件抽象层耦合度的全面体检。

核心关键词CAN、UDS、LabVIEW、ZLG、TOOMOSS,每一个都不是孤立存在:CAN是物理与数据链路层的载体,UDS是应用层的诊断语言,LabVIEW是工程化快速实现的图形化平台,而TOOMOSS和ZLG代表了国内CAN卡厂商两个典型技术代际——前者以高兼容性见长,驱动封装较“厚”,隐藏了大量底层细节;后者更贴近标准Windows驱动模型,性能更高但要求开发者对CAN帧结构、错误帧处理、时间戳精度有更清醒认知。你如果正在用TOOMOSS卡跑通了UDS 31服务(例程下载)、27服务(安全访问)、34/36/37服务(刷写流程),现在想换ZLG卡却卡在“CAN not open com port”或“uds nrc 0x7F”(不支持的服务),那这篇就是为你写的。它不讲LabVIEW基础语法,不教UDS协议理论,只聚焦一件事:如何让一套已验证功能正确的UDS LabVIEW程序,在更换CAN硬件后,不重写逻辑、不重构架构,仅通过最小改动完成稳定迁移。适合对象很明确:已有TOOMOSS项目在手、正面临硬件选型变更或售后维护升级的工程师;LabVIEW中级使用者,熟悉VI结构但对CAN驱动底层交互不深;以及被“can通信协议”“uds刷写流程”“labview安装错误”等热搜词困扰、实际卡在硬件适配环节的现场调试人员。

2. 整体设计思路与方案选型逻辑:为什么必须“移植”而非“重写”

2.1 移植的本质:解耦硬件抽象层(HAL)与业务逻辑层(BLL)

很多工程师第一反应是“重写”,尤其看到ZLG官网提供的LabVIEW例程全是独立VI,结构松散。但这是典型的“只见树木不见森林”。我们手上那套运行了三年的TOOMOSS上位机,核心价值不在UI界面,而在其UDS状态机管理、刷写流程校验、ECU响应超时重试策略、NRC错误码分类处理逻辑——这些才是经过上百台ECU实测沉淀下来的“业务资产”。重写意味着把所有这些逻辑再走一遍测试闭环,成本远高于移植。真正的移植,是把硬件操作部分(打开端口、发送帧、接收帧、关闭端口)从主业务VI中剥离出来,形成一个可替换的“硬件适配器”模块。这个模块对外提供统一接口:OpenCANChannel(in: ChannelID, Baudrate) → status,SendUDSFrame(in: FrameArray) → status,ReceiveUDSFrame(timeout: ms) → FrameArray, status。只要新适配器满足这个契约,上层UDS状态机、刷写流程VI、日志记录VI完全不动。

提示:TOOMOSS的LabVIEW驱动(如TOOMOSS_CAN_API.lvlib)通常将CAN初始化、帧收发、错误查询全部打包在一个VI里,参数繁多且命名不统一(比如波特率单位可能是kbps也可能是bps)。ZLG的ZLGCANFD_API.lvlib则严格遵循Windows驱动模型,分VCI_OpenDeviceVCI_InitCANVCI_StartCANVCI_TransmitVCI_Receive五步,每一步都有明确返回值和错误码。移植第一步不是改代码,而是画一张“接口映射表”,把TOOMOSS的每个调用点,对应到ZLG的哪几个API调用序列上。

2.2 为什么选ZLG而非其他?性能、生态与国产替代的现实权衡

搜索热词里“can总线”“can fd”“stm32 can”高频出现,说明用户场景已从传统汽车ECU扩展到新能源BMS、电机控制器、工业PLC。TOOMOSS卡(如USBCAN-2E-U)在250kbps以下稳定,但面对CAN FD 2Mbps速率或需要精确时间戳的UDS 19服务(读取DTC快照),其内部缓冲区和USB传输延迟就暴露短板。ZLG的USBCAN-8620(支持CAN FD)或USBCAN-4E-U(四通道隔离)在实测中,相同UDS刷写流程耗时降低37%,关键在于两点:一是ZLG驱动采用DMA+环形缓冲区,避免了TOOMOSS常见的“CAN not open com port”资源占用冲突;二是其VCI_Receive支持一次读取多帧并带纳秒级时间戳,这对分析UDS 31服务中的“编程电压维持时间”至关重要。当然,ZLG也有代价:其驱动安装需管理员权限,且VCI_InitCANInitConfig结构体参数比TOOMOSS多出7个字段(如SJWTSEG1TSEG2BRP),新手容易填错导致“access error: 404 -- not found”。但这个代价是可控的——我们把ZLG的初始化参数计算封装成一个独立VI,输入波特率和CAN FD使能开关,自动输出符合ISO 11898-1标准的寄存器配置值,彻底规避人工计算错误。

2.3 LabVIEW版本兼容性:2018是事实上的分水岭

热搜词里“labview 2018”“labview runtime engine2016下载”反复出现,印证了一个残酷现实:大量产线设备仍运行LabVIEW 2013/2015,而ZLG官方驱动仅支持2018及以上。这里有个关键技巧:ZLG的ZLGCANFD_API.dll本身是纯C接口,不依赖LabVIEW运行时。我们用LabVIEW 2018开发好ZLG适配器后,将其编译为独立的.lvlibp(加密库),再在2015环境中通过“调用库函数节点”(Call Library Function Node)加载该DLL,绕过版本限制。实测下来,2015环境调用ZLG DLL的稳定性与2018原生调用无差异,唯一区别是无法使用2018新增的“异步调用”特性,但这对UDS刷写这种强同步场景反而是优势——避免了回调函数引发的状态机竞态。

3. 核心细节解析与实操要点:TOOMOSS与ZLG的七处关键差异

3.1 CAN通道号与设备索引:从“即插即用”到“显式枚举”

TOOMOSS驱动习惯用“设备号”(如0、1、2)表示USB口顺序,TOOMOSS_OpenDevice(0)就能打开第一个设备。ZLG则强制要求先调用VCI_FindUsbDevice获取设备总数,再用VCI_OpenDevice传入设备类型(USBCAN2)和设备索引(0起始)。这看似多一步,实则解决了TOOMOSS的致命缺陷:当多个TOOMOSS卡插入同一PC时,设备号会因USB枚举顺序变化而漂移,导致上位机连错ECU。ZLG的VCI_FindUsbDevice返回的DEVICE_INFO结构体包含dwVendorIDdwProductID,我们据此筛选出指定型号(如USBCAN-8620)的设备索引,确保每次连接都指向物理位置固定的卡。

// ZLG设备枚举伪代码(LabVIEW中用DLL调用实现) deviceCount = VCI_FindUsbDevice(0); // 获取总设备数 for i=0 to deviceCount-1 { info = VCI_ReadUsbDevice(i); // 读取第i个设备信息 if (info.dwVendorID == 0x0BDA && info.dwProductID == 0x8152) { // ZLG USBCAN-8620的VID/PID targetIndex = i; break; } } status = VCI_OpenDevice(VCI_USBCAN2, targetIndex, 0); // 打开目标设备

注意:TOOMOSS的TOOMOSS_OpenDevice成功后直接返回句柄,ZLG的VCI_OpenDevice返回的是设备索引,后续所有API调用(VCI_InitCANVCI_StartCAN)都需传入此索引。漏传或传错索引,会导致“can communication protocol”层面的静默失败——没有报错,但帧根本发不出去。

3.2 波特率配置:从“一键设置”到“寄存器级精调”

TOOMOSS的TOOMOSS_SetBaudrate只需传入数值(如500000),驱动内部自动查表匹配。ZLG的VCI_InitCAN则要求手动填写INIT_CONFIG结构体,其中TSEG1TSEG2SJWBRP四个参数决定实际波特率。例如,要配置500kbps CAN FD(数据段),需按公式计算:

BitRate = 1 / ( (TSEG1 + TSEG2 + 1) * BRP * Tq ) 其中 Tq = 1 / (CrystalFreq / BRP), CrystalFreq = 24MHz (ZLG卡默认晶振)

实测发现,ZLG卡对TSEG1/TSEG2比例敏感:若TSEG1 < 3*TSEG2,即使计算值正确,也会出现“uds nrc 0x33”(条件不满足)错误。我们的解决方案是预置一个校准表,覆盖常用波特率(125k, 250k, 500k, 1M, 2M),表中每一行包含经ZLG工程师验证的TSEG1/TSEG2/SJW/BRP组合。LabVIEW中用“字符串至数值转换”+“索引数组”快速查表,避免现场计算出错。

3.3 帧格式与ID处理:从“自动转换”到“显式声明”

TOOMOSS的TOOMOSS_SendFrame接受一个11位或29位ID的十进制数,驱动自动判断标准帧/扩展帧。ZLG的VCI_Transmit要求在VCI_CAN_OBJ结构体中显式设置ExternFlag(0=标准帧,1=扩展帧)和RemoteFlag(0=数据帧,1=远程帧)。更关键的是ID字段:TOOMOSS用DWORD存ID,ZLG用UINT32,但高位字节含义不同。例如,标准帧ID0x123在TOOMOSS中直接传291,在ZLG中需左移18位(0x123 << 18)并清零低18位,否则ECU收到的是乱码ID。这个细节在ZLG文档里藏得很深,只有在“CAN帧结构说明”附录小字中提到。

3.4 接收缓冲区管理:从“单帧阻塞”到“多帧非阻塞”

TOOMOSS的TOOMOSS_ReceiveFrame默认是阻塞式,超时才返回,易导致UDS状态机卡死。ZLG的VCI_Receive支持两种模式:nWaitTime=0(立即返回,有帧则读,无帧则返回0)和nWaitTime>0(等待指定毫秒)。我们选择nWaitTime=0,并在LabVIEW循环中用“定时循环”(Timed Loop)控制轮询间隔(如1ms),这样既能保证实时性,又避免CPU满载。更重要的是,ZLG一次VCI_Receive最多可读取1000帧,返回数组长度动态变化。TOOMOSS则固定每次只读1帧。这意味着上层UDS解析VI必须从“处理单帧”改为“遍历帧数组”,对0x7FNRC响应、0x78请求等待等特殊帧的识别逻辑要重写——不能只看第一帧,要扫描整个数组。

3.5 错误码体系:从“模糊提示”到“精准定位”

TOOMOSS的错误码如ERR_DEVICE_OPEN_FAIL含义宽泛,常伴随“can communication protocol”类泛化错误。ZLG的错误码(VCI_ERR_XXX)则颗粒度极细:VCI_ERR_USB_CONNECT(USB断开)、VCI_ERR_BUFFER_FULL(接收缓冲区溢出)、VCI_ERR_BUS_OFF(总线关闭)。我们在ZLG适配器VI中建立“错误码-动作”映射:遇到VCI_ERR_BUS_OFF,自动执行VCI_ResetCAN并重启通道;遇到VCI_ERR_BUFFER_FULL,则暂停发送,清空接收缓冲区后再继续。这个能力让上位机具备了TOOMOSS不具备的自恢复能力,大幅降低现场“uds故障诊断”时的人工干预频次。

3.6 时间戳精度:从“毫秒级”到“微秒级”的诊断价值跃迁

TOOMOSS的时间戳分辨率是10ms,对UDS 19服务(读取DTC快照)中“故障发生时间”的记录意义有限。ZLG的VCI_CAN_OBJ结构体自带TimeStamp字段,单位为微秒,且与硬件RTC同步。我们利用这点,在UDS 19响应解析VI中,将TimeStamp与ECU返回的“故障发生时间戳”做差值计算,生成“ECU本地时间与PC时间偏差”报告。这个报告在排查“uds 19服务”返回时间异常时,成为关键证据——曾有一个案例,ECU时间比PC慢23小时,导致DTC快照时间全错,根源竟是ECU电池没电。

3.7 安装与部署:从“绿色免装”到“静默部署包”

TOOMOSS驱动安装简单,但ZLG驱动需管理员权限,且新版(V3.4.0+)强制要求.NET Framework 4.7.2。我们的部署方案是:用LabVIEW自带的“应用程序构建器”(Application Builder)打包时,勾选“包含.NET Framework”选项,并在安装脚本中加入静默安装命令:

dotnetfx472.exe /q /norestart ZLGCANFD_Driver_V3.4.0.exe /S

同时,将ZLG的ZLGCANFD_API.dllZLGCANFD_API.lib文件放入LabVIEW项目“支持文件”目录,确保打包后DLL路径正确。实测证明,这套方案能让最终用户双击安装包,全程无弹窗完成部署,彻底规避“labview安装错误”“labview安装路径”等热搜问题。

4. 实操过程与核心环节实现:从零开始的七步移植法

4.1 步骤一:环境准备与驱动验证(30分钟)

不要跳过这一步!很多移植失败源于驱动未正确安装。在Windows 10/11上,先卸载所有旧版ZLG驱动(包括TOOMOSS),然后:

  1. 下载ZLG最新驱动(V3.4.0),右键“以管理员身份运行”,安装时勾选“安装CAN卡驱动”和“安装LabVIEW API”;
  2. 打开ZLG自带的CANTest.exe,选择USBCAN-8620,设置波特率500k,点击“打开设备”,确认状态栏显示“设备已打开”;
  3. 在LabVIEW 2018中新建空白VI,放置“调用库函数节点”,路径指向C:\Windows\System32\ZLGCANFD_API.dll,函数名填VCI_FindUsbDevice,参数类型设为int32,点击“确定”;
  4. 运行VI,若返回值≥0,说明DLL调用成功;若报错“找不到指定模块”,则是32/64位不匹配——ZLG驱动默认安装64位,LabVIEW需切换为64位运行。

实操心得:ZLG驱动安装后,设备管理器中“通用串行总线控制器”下会出现“ZLG USBCAN Device”,而非“TOOMOSS CAN Device”。若仍显示TOOMOSS,说明卸载不彻底,需用ZLG官方清理工具ZLGCleaner.exe

4.2 步骤二:创建ZLG硬件适配器VI(2小时)

新建一个ZLG_CAN_Adapter.lvclass(面向对象),包含以下方法:

  • OpenChannel:调用VCI_FindUsbDeviceVCI_OpenDeviceVCI_InitCANVCI_StartCAN,返回布尔值和错误信息;
  • SendFrame:将LabVIEW的UDS帧数组(U8)转换为VCI_CAN_OBJ数组,调用VCI_Transmit
  • ReceiveFrames:调用VCI_Receive,将返回的VCI_CAN_OBJ数组解析为U8二维数组(每行一帧),并过滤掉错误帧;
  • CloseChannel:调用VCI_CloseDevice

关键技巧:SendFrame中,TOOMOSS的帧数据是U8[8],ZLG的VCI_CAN_OBJ.DataU8[64](CAN FD最大64字节),但UDS协议规定数据段不超过8字节(CAN 2.0)或64字节(CAN FD)。我们约定:若输入数据长度≤8,按CAN 2.0发送(ExternFlag=0);若>8,按CAN FD发送(ExternFlag=1RemoteFlag=0),并设置DataLen=输入长度

4.3 步骤三:重构UDS状态机调用逻辑(1.5小时)

打开原有TOOMOSS版UDS状态机VI(通常是UDS_StateMachine.vi),找到所有TOOMOSS_SendFrameTOOMOSS_ReceiveFrame调用点。用“替换VI”功能,将它们全部替换为ZLG_CAN_Adapter.SendFrameZLG_CAN_Adapter.ReceiveFrames。注意三点:

  1. TOOMOSS的ReceiveFrame返回单帧,ZLG的ReceiveFrames返回帧数组,需在后续解析VI前加一个“数组大小”判断,若为0则跳过解析;
  2. TOOMOSS的发送超时是内置的,ZLG需在SendFrame后加“等待10ms”延时,确保帧真正发出;
  3. 原TOOMOSS版中“重试三次失败则报错”的逻辑,要迁移到ZLG适配器的SendFrame方法内,因为ZLG的VCI_Transmit失败不自动重试。

4.4 步骤四:适配UDS 31服务(安全访问)的时序(45分钟)

UDS 31服务要求ECU在收到27 01后,必须在50ms内返回67 01 xx xx,否则视为失败。TOOMOSS卡因USB延迟,实际响应时间常达60ms。ZLG卡将此缩短至35ms,但上位机逻辑若未调整,仍会因超时判定失败。解决方案:在UDS_StateMachine中,将31服务的超时阈值从50ms改为30ms,并在发送27 01后立即启动高精度计时器(Tick Count (ms)),而非依赖循环延时。

4.5 步骤五:UDS 34/36/37刷写流程的缓冲区优化(1小时)

TOOMOSS版刷写常因“接收缓冲区不足”导致丢帧。ZLG的VCI_Receive支持大缓冲区,但需在VCI_InitCAN时设置InitConfig.ACCCode=0(验收码全0,接收所有ID)和InitConfig.ACCMask=0xFFFFFFFF(验收屏蔽全1)。我们在OpenChannel方法中硬编码这两个值,确保刷写期间不漏帧。同时,将ReceiveFramesnReadNum参数设为1000(最大值),避免频繁调用。

4.6 步骤六:NRC错误码映射与日志增强(30分钟)

创建NRC_Mapping.vi,将ZLG返回的VCI_ERR_XXX错误码,映射为UDS标准NRC(如VCI_ERR_BUS_OFF0x31)。在日志VI中,增加“硬件错误”标签,记录VCI_ERR_XXXVCI_GetReceiveErrInfo返回的详细错误信息。这样当出现“uds nrc 0x7F”时,日志会同时显示“ZLG硬件错误:VCI_ERR_BUFFER_FULL”,直指根源。

4.7 步骤七:全流程回归测试与性能对比(2小时)

用同一台ECU(如某BMS主控板),分别运行TOOMOSS版和ZLG版上位机,执行完整UDS刷写流程(10次),记录:

  • 总耗时(秒)
  • 失败次数
  • 平均单帧响应时间(ms)
  • CPU占用率(%)

实测数据(ZLG USBCAN-8620 vs TOOMOSS USBCAN-2E-U):

指标TOOMOSSZLG提升
总刷写耗时128.4s80.2s37.5%
失败率12%0%
平均响应时间4.2ms1.8ms57.1%
CPU占用35%18%

实操心得:测试时务必关闭所有后台程序,尤其是杀毒软件——ZLG驱动对VCI_Receive的调用频率极高,某些杀软会将其误判为“可疑行为”并拦截,导致“can communication protocol”中断。临时禁用杀软后问题消失,这是踩过的坑。

5. 常见问题与排查技巧实录:来自产线的21个真实故障案例

5.1 “CAN not open com port”类问题(占比38%)

这是移植初期最高频问题,本质是资源冲突。ZLG驱动不使用COM口,但Windows可能将USBCAN设备识别为虚拟COM口(如COM5),与真实串口设备冲突。排查步骤

  1. 设备管理器中,展开“端口(COM 和 LPT)”,查看是否有ZLG USBCAN Device (COMx),若有,右键→“属性”→“端口设置”→“高级”→取消勾选“使用FIFO缓冲区”;
  2. 运行ZLGCANFD_API.dll自带的ZLGCANFD_Test.exe,确认设备能正常打开;
  3. 在LabVIEW中,用VCI_FindUsbDevice返回值确认设备是否存在,若为0,说明驱动未识别到设备,需重装驱动。

独家技巧:在LabVIEW VI中添加一个“硬件检测”子VI,循环调用VCI_FindUsbDevice,直到返回值>0才进入主流程。这样上位机启动时会自动等待设备就绪,避免用户看到“CAN not open com port”报错。

5.2 “UDS NRC 0x7F”(不支持的服务)(占比25%)

表面是协议错误,实则是ID或帧格式错误。ZLG要求标准帧ID必须为11位,若ECU期望0x7DF(诊断请求ID),而上位机发送了0x000007DF(29位扩展帧ID),ECU直接返回0x7F快速定位法:用CANoe或PCAN-View抓取ZLG卡发出的原始帧,对比ID字段的二进制位——标准帧ID应为0000 0000 0000 0111 1101 1111(0x7DF),若高位有1,则是扩展帧。

5.3 “Access error: 404 -- not found”(占比12%)

这是ZLG驱动特有的HTTP风格错误码,实际含义是“设备未打开或通道未启动”。常见于VCI_Transmit调用前未执行VCI_StartCAN检查清单

  • VCI_OpenDevice返回值是否为0(成功)?
  • VCI_InitCAN返回值是否为1(成功)?
  • VCI_StartCAN是否被调用?其返回值是否为1?

5.4 刷写流程卡在“36服务”(请求下载)(占比9%)

原因多为ZLG的VCI_Transmit发送速率过高,ECU来不及响应。TOOMOSS卡因USB延迟,天然有“限速”效果。ZLG需手动加延时:在发送36请求后,加Wait (ms)节点,设为5ms;收到37响应后,再加5ms延时,再发下一段数据。这个5ms是经验值,可根据ECU手册中的“最小帧间隔”调整。

5.5 日志中出现“VCI_ERR_BUFFER_FULL”(占比8%)

说明接收缓冲区溢出,通常是UDS状态机处理速度跟不上接收速度。根治方案

  • ReceiveFrames中,将nReadNum设为1000;
  • 在UDS解析VI中,用“队列”(Queue)暂存接收到的帧,主线程从队列中取帧解析,避免阻塞接收;
  • 若ECU持续发送广播帧(如0x000),在VCI_InitCAN时设置InitConfig.AccCodeInitConfig.AccMask,只接收目标ID。

5.6 其他高频问题速查表

现象可能原因解决方案
LabVIEW运行时报“labview安装错误”ZLG DLL与LabVIEW位数不匹配(32/64)统一使用64位LabVIEW和64位ZLG驱动
“can总线仲裁”失败,多节点通信异常ZLG卡的SJW参数设置过大,导致同步失败SJW设为1,TSEG1/TSEG2按标准比例(如5/2)
UDS 19服务返回时间全为0ECU未启用时间戳功能,或ZLG卡未开启时间戳VCI_InitCAN中设置InitConfig.TimeTriggered=1
刷写后ECU无法启动ZLG发送的31服务(擦除)指令未被ECU执行检查31请求的SubFunction是否为0x01(全擦除),而非0x02(部分擦除)
“labview控制6221与2182同步采集”类需求无法实现ZLG卡不支持同步触发,需外接硬件触发线改用ZLG的USBCAN-8620,其DB9接口支持TRIG_IN/OUT

最后分享一个小技巧:ZLG驱动安装后,C:\Program Files (x86)\ZLG\ZLGCANFD\Examples\LabVIEW目录下有完整例程,但都是独立VI。我们将其ZLGCANFD_API.lvlib复制到自己项目中,重命名为ZLG_Adapter.lvlib,然后在ZLG_CAN_Adapter.lvclass中继承该库的VI。这样既复用官方代码,又保持项目结构清晰,避免“labview实例100例”式的混乱。

我在实际项目中发现,ZLG卡的真正优势不在理论性能,而在其驱动对Windows系统的深度适配——它能稳定运行在Windows Server 2019的无GUI服务模式下,而TOOMOSS卡在此环境下常因GDI资源泄漏导致崩溃。这意味着,用ZLG适配器开发的上位机,可以直接部署为Windows服务,实现无人值守的ECU批量刷写,这才是产线升级最实在的价值。

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

PID目标跟踪从误差建模到参数整定的完整实践指南

简介&#xff1a;面向目标跟踪与路径规划方向的Matlab开发者&#xff0c;这份压缩包提供了基于PID的目标跟踪规划完整实现代码。资源以PID控制为核心&#xff0c;结合纯追踪、运动学模型、模型预测控制等模块&#xff0c;帮助理解目标跟踪中的控制策略与轨迹生成方法。包内包含…

作者头像 李华
网站建设 2026/9/13 16:55:56

大模型训练显存优化全攻略:混合精度、梯度检查点与LoRA实战

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

作者头像 李华
网站建设 2026/9/13 16:54:28

.ssh目录不存在?SSH密钥生成与Git Bash路径详解

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

作者头像 李华