TI C6000 DSP时钟系统深度解析:从PLL配置到外设时钟实战 1. 项目概述与核心价值在嵌入式系统开发尤其是基于TI C6000系列DSP的项目中时钟系统的设计往往是决定系统稳定性、性能和功耗的关键却也是最容易被开发者忽视或感到棘手的部分。你可能遇到过这样的场景代码逻辑没问题外设驱动也写好了但USB通信时断时续EMIF接口读写SDRAM偶尔会出错或者系统在特定频率下功耗异常增高。这些问题十有八九根子在时钟配置上。时钟就像是整个芯片的“心跳”心跳乱了各个器官外设自然无法协调工作。我接触过不少工程师他们拿到芯片手册看到PLL、SYSCLK、DIV4P5、POSTDIV这些名词和密密麻麻的时钟树框图第一反应是头大往往选择照搬参考设计或SDK里的默认配置。这在小批量、功能简单的项目中或许能蒙混过关但一旦涉及到性能调优、低功耗设计或者需要为特定外设如需要精确50MHz RMII时钟的以太网PHY定制时钟时这种“黑盒”操作就会带来无尽的调试噩梦。本文将以TI官方文档SPRUH91D针对OMAP-L138/C6748等器件为蓝本但不止于翻译手册。我将结合自己多年在通信和工业控制领域使用TI DSP的实战经验为你彻底拆解这颗芯片的时钟架构。我们会从锁相环PLL的基本工作原理讲起但重点会放在如何根据你的具体需求去计算、配置并验证整个时钟树。你会明白每个寄存器位PLLM, POSTDIV, PLLDIVn的真实含义知道SYSCLK1到SYSCLK7每个时钟域是给谁用的以及如何为EMIFA、EMIFB、USB、EMAC这些“挑食”的外设搭配出合适的“时钟餐”。更重要的是我会分享那些数据手册里不会写的配置陷阱、锁定时序的微妙之处以及调试时钟问题时最有效的排查手段。无论你是正在评估芯片选型还是深陷时钟相关的Bug调试这篇文章都能提供一条清晰的路径和可实操的“地图”。2. 时钟架构核心思想与设计思路拆解在深入寄存器之前我们必须先建立对TI DSP时钟系统的顶层认知。它的设计核心思想可以概括为“一个主心骨多条分支流兼顾灵活与约束”。2.1 “一个主心骨”PLL控制器PLLC的核心地位整个系统的时钟源头是输入到OSCIN引脚的外部参考时钟可以是晶体振荡器或外部时钟源。这个频率例如常见的24MHz、25MHz、30MHz相对较低且固定。PLLC的作用就是扮演一个高性能的“频率合成器”将低频的OSCIN倍频到一个很高的核心频率PLL输出频率可达数百MHz。之后所有系统时钟都源于这个被“放大”后的核心频率。这里的关键在于PLLC提供了两种工作模式旁路模式Bypass ModePLL被绕过OSCIN直接作为系统时钟源。这是上电复位后的默认状态也是一种低功耗模式。此时系统运行在较低的参考时钟频率下。活动模式Active ModePLL启用对OSCIN进行倍频以其输出作为系统时钟源。这是高性能工作状态。2.2 “多条分支流”系统时钟域SYSCLK的划分PLL产生的核心高频时钟并不能直接用于所有模块。不同外设对时钟频率、相位噪声、功耗的要求天差地别。因此芯片内部通过一系列分频器PLLDIV将核心时钟“分流”成多个不同的时钟域即SYSCLK1到SYSCLK7。这是整个时钟设计的精髓。根据它们与CPU时钟SYSCLK1的关系这些时钟域可分为两类固定比例时钟域如SYSCLK1DSP核、SYSCLK2EDMA, UART等、SYSCLK4系统配置GPIO等。它们的频率与CPU时钟保持固定的整数分频比如1:1, 1:2, 1:4。这意味着当你改变CPU主频时这些外设的时钟会按比例自动变化保持同步。这简化了软件设计但限制了外设时钟的独立性。非固定比例时钟域如SYSCLK3EMIFA、SYSCLK5EMIFB I/O、SYSCLK7EMAC RMII参考。它们的分频比可以独立于CPU时钟进行编程。这带来了巨大的灵活性允许你为EMIF内存接口或以太网MAC单独设置一个最合适的频率而不必受限于CPU主频。这也是最容易配置出错的地方。2.3 设计思路从需求反推配置很多新手会正着看时钟树先设PLL再分SYSCLK。但正确的设计思路应该是反着来的确定外设需求你的项目里用了哪些外设EMIFA要接多少速率的异步存储器EMIFB的SDRAM时钟EMB_CLK需要多少USB需要48MHz参考时钟吗EMAC要用RMII模式且需要精确的50MHz吗确定CPU性能需求DSP内核需要跑多少MHz这决定了SYSCLK1的频率。寻找交汇点根据1和2列出所有必需的时钟频率。然后以OSCIN假设已选定如25MHz和PLL输出频率为变量尝试解方程找到一组PLL倍频器PLLM、后分频器POSTDIV以及各个PLLDIV的配置使得所有SYSCLK频率都满足需求且不超过芯片手册规定的最大频率限制。优化与权衡通常有多组解。此时需要考虑功耗PLL输出频率越高功耗越大手册中明确提示、电磁兼容性以及配置的简洁性。举个例子假设你的设计需要CPU: 300 MHz (SYSCLK1)EMIFB SDRAM: 133 MHz (EMB_CLK)OSCIN: 25 MHz一种直观的配置是PLLM 24 (25MHz * 24 600MHz)POSTDIV /2 (600MHz / 2 300MHz) 得到CPU频率。EMB_CLK可以从DIV4P5获得 (600MHz / 4.5 ≈ 133.33MHz)。这看起来完美。但如果你还需要SYSCLK7输出精确的50MHz给RMII你会发现300MHz的SYSCLK1无论怎么分频/6后是50MHz其精度都受限于25MHz晶振和PLL的抖动可能无法满足RMII严格的±50ppm精度要求。这时你就必须考虑使用外部专用的50MHz时钟源直接提供给RMII_MHZ_50_CLK引脚。这种外设需求与时钟树能力的匹配是设计初期就必须厘清的。3. PLL配置详解从理论到寄存器操作理解了架构我们开始动手配置。PLL的配置主要围绕几个核心寄存器PLLCTL控制、PLLM倍频、POSTDIV后分频、PLLDIVn各时钟域分频。3.1 PLL工作模式切换与上电序列芯片上电或复位后PLL处于旁路模式且掉电状态PLLPWRDN1。要让系统跑在高频必须按严格顺序初始化PLL。手册里的步骤看起来繁琐但每一步都有其物理意义打乱顺序可能导致时钟毛刺甚至锁死。注意以下操作涉及对PLL控制器的写操作。如果系统已经启用了看门狗运行在AUXCLK上且看门狗超时时间较短那么在配置PLL期间如果AUXCLK被意外关闭或大幅改变可能触发看门狗复位。因此在修改PLL前通常需要先解锁寄存器写保护通过KICK0/KICK1和CFGCHIP0.PLL_MASTER_LOCK位必要时先禁用看门狗。完整的PLL初始化流程从掉电到活动模式如下确保进入旁路模式即使PLL还未上电也先显式设置PLLCTL.PLLEN 0并复位PLLPLLCTL.PLLRST 0。等待至少4个OSCIN周期。这一步是建立一个干净的起点。配置时钟源模式通过PLLCTL.CLKMODE选择是使用外部晶体还是外部时钟输入。通常使用晶体模式。唤醒PLL清除PLLCTL.PLLPWRDN 0给PLL模拟电路上电。设置倍频与分频这是核心计算步骤。写入PLLM寄存器设置倍频系数N。例如OSCIN25MHz想要PLL输出600MHz则N24因为PLLM寄存值 N 即写入24。写入POSTDIV寄存器设置后分频比/1, /2, /3, /4等。这用于初步降低频率以降低后续分频器压力。写入各个PLLDIVn寄存器设置每个SYSCLK域的分频比。例如设置PLLDIV1.RATIO 0表示对POSTDIV输出进行/1分频得到SYSCLK1PLLDIV2.RATIO 1表示/2分频得到SYSCLK2。执行“GO”操作在更改了任何PLLDIVn的分频比后必须触发一个相位对齐过程。方法是先检查PLLSTAT.GOSTAT是否为0表示空闲然后设置PLLCMD.GOSET 1再轮询等待PLLSTAT.GOSTAT变回0。这一步至关重要缺失会导致各时钟域相位不同步引发数据传输错误。释放PLL复位设置PLLCTL.PLLRST 1让PLL开始工作。等待锁定PLL需要时间锁定到目标频率。这个锁定时间Lock Time在芯片数据手册的电气特性章节有明确规定通常是几十到上百微秒。你必须通过延时函数等待足够时间不能通过查询某个状态位来等待该系列PLL通常不提供锁相完成状态位。切换到PLL模式最后设置PLLCTL.PLLEN 1。系统时钟瞬间从慢速的OSCIN切换到高速且稳定的PLL输出系统开始全速运行。3.2 关键参数计算与配置实例让我们用一个典型配置来串联上述步骤。目标OSCIN25MHzSYSCLK1300MHzSYSCLK475MHz固定1:4EMIFB_CLK133MHz。步骤1确定PLL输出频率。我们希望SYSCLK1300MHz。如果设置POSTDIV /2那么POSTDIV的输入频率即PLL输出频率应为600MHz。步骤2计算PLL倍频系数。PLL输出频率 OSCIN*PLLM。因此PLLM 600MHz / 25MHz 24。步骤3配置分频器。POSTDIV.RATIO 1 (代表 /2 模式)。PLLDIV1.RATIO 0 (对300MHz进行 /1 得到SYSCLK1300MHz)。PLLDIV2.RATIO 1 (对300MHz进行 /2 得到SYSCLK2150MHz)。这是固定比例必须为1。PLLDIV4.RATIO 3 (对300MHz进行 /4 得到SYSCLK475MHz)。这是固定比例必须为3。PLLDIV5.RATIO ? 这是给SYSCLK5的但EMIFB的MCLK可以选择SYSCLK5或DIV4P5。为了得到133MHz我们选择DIV4P5。DIV4P5是固定/4.5分频器输入是PLL输出频率600MHz输出为600/4.5 ≈ 133.33MHz。因此我们不需要配置PLLDIV5而是通过CFGCHIP3.EMB_CLKSRC选择DIV4P5作为EMIFB的MCLK源。步骤4寄存器写入。假设我们已经解锁了写保护代码如下以C语言伪代码为例// 1. 确保旁路并复位PLL PLLCTL ~(1 0); // PLLEN 0 PLLCTL ~(1 3); // PLLRST 0 delay_cycles(4 * OSCIN_CYCLES); // 简单延时 // 2. 配置时钟源假设为晶体模式 // PLLCTL.CLKMODE 默认为0晶体模式通常不需改动 // 3. 给PLL上电 PLLCTL ~(1 1); // PLLPWRDN 0 // 4. 设置倍频和后分频 PLLM 24; // 设置倍频系数为24 POSTDIV 1; // 设置后分频为 /2 // 5. 设置SYSCLK分频器 PLLDIV1 0; // SYSCLK1 /1 PLLDIV2 1; // SYSCLK2 /2 (固定) PLLDIV4 3; // SYSCLK4 /4 (固定) // PLLDIV3,5,7 根据其他外设需求配置此处暂不设置 // 6. 执行GO操作同步分频器变更 while (PLLSTAT (1 0)); // 等待GOSTAT为0 PLLCMD | (1 0); // 设置GOSET1 while (PLLSTAT (1 0)); // 等待GOSTAT变回0 // 7. 释放PLL复位 PLLCTL | (1 3); // PLLRST 1 // 8. 等待PLL锁定需查阅数据手册获取具体时间例如200us delay_us(200); // 9. 切换到PLL时钟 PLLCTL | (1 0); // PLLEN 13.3 功耗优化技巧手册中特别强调PLL功耗与其输出频率成正比。因此在满足所有时钟需求的前提下应尽量降低PLL的输出频率。例如同样为了得到300MHz的SYSCLK1你可以选择PLLM24, POSTDIV/2PLL输出600MHz也可以选择PLLM30, POSTDIV/3PLL输出750MHz。虽然最终CPU频率一样但后者的PLL工作在更高频率功耗和发热都会更大。因此优先采用更大的后分频比POSTDIV和更小的倍频系数PLLM来达成目标频率是低功耗设计的一个小窍门。4. 关键外设时钟配置实战与陷阱规避时钟配置好了系统能跑起来了但外设可能还在“闹脾气”。这是因为许多高速外设有自己特殊的时钟要求和选择器。这部分是手册的精华也是实战的坑点。4.1 USB时钟配置内部PLL与外部REFCLK的抉择USB模块尤其是USB 2.0对时钟的精度和稳定性要求极高。TI DSP的USB子系统有一个内部PHY PLL它需要一个参考时钟。这个参考时钟可以来自两个地方专用的USB_REFCLKIN引脚外部提供。芯片内部PLL产生的AUXCLK。如何选择这取决于你的应用和硬件设计。场景A需要高精度USB时钟如USB Audio Class设备。必须使用外部高精度晶振如24MHz连接到USB_REFCLKIN引脚。然后配置CFGCHIP2.USB0PHYCLKMUX0选择此路时钟。这样USB时钟与主系统时钟完全独立不受DSP主PLL抖动的影响。场景B节省一个外部晶振且对USB时钟精度要求不极端如USB CDC虚拟串口。可以使用内部的AUXCLK。AUXCLK来源于OSCIN可能经过PLL。你需要确保AUXCLK的频率是USB PHY PLL支持的输入频率之一如12, 24, 48MHz等。然后配置CFGCHIP2.USB0PHYCLKMUX1。重大陷阱USB1.1的时钟依赖关系。如果你的芯片支持USB1.1如OMAP-L138并且你使用了它要特别注意其48MHz时钟CLK48的来源。它可以从USB_REFCLKIN来也可以从USB2.0 PHY产生的48MHz时钟来。如果你选择从USB2.0 PHY获取CFGCHIP2.USB1PHYCLKMUX0必须强制USB2.0 PHY的PLL始终运行即使USB2.0处于挂起状态。这是通过设置CFGCHIP2.USB0PHY_PLLON1来实现的。否则当USB2.0挂起时其PHY PLL停振USB1.1的时钟就没了会导致系统异常。这个细节在复杂系统中极易被忽略。4.2 EMIFBSDRAM控制器时钟配置性能与功耗的平衡EMIFB需要两个时钟VCLK总线接口时钟来自SYSCLK2和MCLK存储器时钟输出为EMB_CLK。MCLK的来源可以选择SYSCLK5或DIV4P5。这是为了在性能和功耗间取得平衡。DIV4P5一个固定的/4.5分频器输入是PLL的输出频率。它的优点是产生高频时钟效率高例如从600MHz直接得到133MHz且与PLL输出严格同步。缺点是其占空比不是50%而是44.4%。对于大多数SDRAM这个占空比是可以接受的但最好查阅你的SDRAM芯片手册确认。SYSCLK5一个可编程分频器PLLDIV5。你可以通过配置PLLDIV5.RATIO得到更灵活的频率并且占空比是50%。但可能无法直接得到像133.33MHz这样的特定频率。配置建议如果你的SDRAM需要标准的133MHz或100MHz时钟且PLL输出频率能方便地被4.5整除如600MHz, 450MHz优先使用DIV4P5设置CFGCHIP3.EMB_CLKSRC1。这是最简单、最常用的方式。如果你需要非标准的SDRAM时钟频率或者非常严格要求50%占空比则使用SYSCLK5CFGCHIP3.EMB_CLKSRC0并精心计算PLLDIV5的分频比。另一个重要配置是PINMUX0[15:12]它选择EMB_CLK引脚输出的时钟源。有两个选项CLK1来自EMIFB模块的LPSC时钟门控之后。这意味着当通过电源睡眠控制器LPSC关闭EMIFB模块时钟时EMB_CLK引脚也会停止输出。这是连接外部SDRAM时的正确选择因为关闭时钟可以省电。CLK2直接来自MCLK的选择器DIV4P5或SYSCLK5输出绕过LPSC。这意味着即使EMIFB模块被关闭EMB_CLK引脚上仍然有时钟。这通常用于将EMB_CLK引脚作为一个通用的自由运行时钟输出给FPGA等其他芯片使用。如果你接的是SDRAM却误选了这个会导致无法通过LPSC关断SDRAM时钟增加不必要的功耗。4.3 EMAC以太网时钟配置RMII的50MHz难题当以太网使用RMII接口时需要提供一个精确的50MHz参考时钟。这个时钟可以由外部PHY芯片提供通过RMII_MHZ_50_CLK引脚输入也可以由DSP内部产生通过SYSCLK7输出到该引脚。手册明确警告SYSCLK7输出的时钟不满足RMII参考时钟±50ppm的精度要求这是因为SYSCLK7来源于主PLL其精度和抖动受限于OSCIN晶振和PLL本身的性能。对于10/100M以太网50ppm的精度要求是很高的普通的25MHz晶振即使精度为±50ppm经过PLL倍频分频后很难保证最终的50MHz时钟依然满足±50ppm。强烈建议在RMII模式下永远使用外部PHY提供的50MHz时钟或者使用一颗独立的、高精度的50MHz振荡器连接到RMII_MHZ_50_CLK引脚。将PINMUX9[23:20]配置为0选择外部时钟输入。这是保证以太网通信长期稳定的基石。试图用SYSCLK7来节省一颗晶振会在网络流量大或温度变化时带来难以排查的间歇性连接问题。5. 系统时钟设计实例与调试心得理论说再多不如一个实例来得清晰。假设我们要为一个数据采集系统设计时钟需求如下DSP需要运行在456MHz以获得足够处理能力。外接一片133MHz的SDRAMEMIFB。外接一片异步NOR FlashEMIFA运行在100MHz。使用USB 2.0高速模式与主机通信。使用RMII以太网与外部通信。主晶振OSCIN为24MHz。5.1 需求分析与时钟规划CPU时钟SYSCLK1 456MHz。EMIFB时钟EMB_CLK需要133MHz。优先考虑使用DIV4P5。那么PLL输出频率需要满足PLL_OUT / 4.5 ≈ 133.33MHz PLL_OUT ≈ 600MHz。EMIFA时钟需要100MHz。EMIFA时钟源可以是SYSCLK3或DIV4P5。既然DIV4P5已经被用于133MHz我们尝试用SYSCLK3来产生100MHz。SYSCLK3 PLL_OUT / POSTDIV / PLLDIV3。我们希望POSTDIV输出一个便于分频的频率。USB时钟为了获得最佳性能我们使用外部24MHz晶振连接到USB_REFCLKIN引脚。以太网时钟使用外部PHY提供的50MHz时钟输入到RMII_MHZ_50_CLK。其他固定比例时钟SYSCLK2 SYSCLK1 / 2 228MHzSYSCLK4 SYSCLK1 / 4 114MHz。5.2 计算与配置方案目标是PLL_OUT 600MHz。已知OSCIN 24MHz。PLLM 600 / 24 25。我们需要POSTDIV的输出为456MHz因为SYSCLK1是/1分频。所以POSTDIV输出 456MHz。那么POSTDIV的分频比 PLL_OUT / POSTDIV输出 600 / 456 1.315... 不是整数。此路不通。我们需要重新规划。既然DIV4P5需要~600MHz我们不妨先固定PLL_OUT 600MHz。然后反推CPU频率。如果我们设置POSTDIV /1那么POSTDIV输出就是600MHz。为了让SYSCLK1456MHz我们需要设置PLLDIV1.RATIO进行分频。但PLLDIV1是固定/1分频RATIO0这里是一个关键点手册指出SYSCLK1/SYSCLK2/SYSCLK4的分频比必须固定为1:2:4但PLLDIV1、PLLDIV2、PLLDIV4的RATIO值是可以编程的只要保证最终频率符合比例。例如我们可以设置 * POSTDIV输出 600MHz *PLLDIV1.RATIO 0(/1) - SYSCLK1 600MHz *PLLDIV2.RATIO 1(/2) - SYSCLK2 300MHz *PLLDIV4.RATIO 3(/4) - SYSCLK4 150MHz 这样虽然SYSCLK1变成了600MHz高于需求的456MHz但满足了固定比例关系。但这样CPU超频了可能超出芯片规格。我们需要降低PLL_OUT。让我们尝试另一个方案放弃DIV4P5产生精确133MHz改用SYSCLK5。这样对PLL_OUT的限制就小了。目标SYSCLK1456MHz SYSCLK5133MHz。设PLL_OUT F, POSTDIV分频比为PPLLDIV1.RATIO0则 F / P 456MHz。SYSCLK5 F / P / D5 133MHz 其中D5是PLLDIV5的分频值。由上式可得 D5 456 / 133 ≈ 3.43。分频器必须是整数取D53则SYSCLK5152MHz太高取D54则SYSCLK5114MHz太低。都无法精确得到133MHz。这说明用SYSCLK5生成133MHz很困难。看来为了满足133MHz SDRAM将PLL_OUT设为600MHz左右并使用DIV4P5是最直接的。那么我们就接受PLL_OUT600MHz并调整CPU频率目标。既然PLLDIV1必须是/1那么SYSCLK1就等于POSTDIV输出。为了让SYSCLK1在一个合理的值我们调整POSTDIV。设PLL_OUT 600MHz。若POSTDIV /1 SYSCLK1600MHz。若POSTDIV /2 SYSCLK1300MHz。若POSTDIV /3 SYSCLK1200MHz。若POSTDIV /4 SYSCLK1150MHz。600MHz对于许多C674x器件来说可能过高需查具体型号手册。300MHz是一个安全且常见的值。我们妥协一下选择SYSCLK1300MHz POSTDIV/2。这意味着CPU性能从456MHz降到了300MHz。你需要评估这个性能是否满足采集处理需求。如果不够可能需要选择更高性能的DSP型号或者使用更高频率的OSCIN如25MHz来重新计算。假设我们最终方案定为OSCIN24MHzPLLM25PLL_OUT600MHzPOSTDIV/2输出300MHz。SYSCLK1 300MHz (PLLDIV10)SYSCLK2 150MHz (PLLDIV21)SYSCLK4 75MHz (PLLDIV43)EMIFB CLK: 使用DIV4P5 600MHz / 4.5 133.33MHz。配置CFGCHIP3.EMB_CLKSRC1。EMIFA CLK: 需要100MHz。使用SYSCLK3。SYSCLK3 300MHz / D3。要得到100MHz D33。配置PLLDIV3.RATIO2因为RATIO2代表/3分频并设置CFGCHIP3.EMA_CLKSRC0选择SYSCLK3。SYSCLK7: 配置一个频率但以太网不用它。例如设为50MHz300MHz / 6配置PLLDIV7.RATIO5。5.3 调试心得与问题排查即使配置计算无误实际硬件上电也可能出问题。以下是我总结的排查清单系统根本不起振程序不运行检查OSCIN引脚是否有正确的时钟波形用示波器。幅度和频率是否在手册要求范围内检查PLL配置代码是否在系统初始化早期被执行确认代码已搬运到内部RAM中运行因为配置PLL时外部Flash可能还不可用。单步调试检查在切换PLLEN位之前是否等待了足够的PLL锁定时间延时太短会导致PLL未锁定就切换系统挂死。系统运行不稳定偶尔死机或数据错误重点检查SDRAMEMIFB相关配置。除了时钟SDRAM的刷新率、时序参数tRAS, tRCD, tRP等是否根据133MHz时钟频率正确计算并配置不稳定的时钟会放大时序裕量不足的问题。用示波器测量EMB_CLK引脚。频率是否正确占空比是否接近50%如果用DIV4P5则是44.4%波形是否干净有无过冲或振铃长距离布线可能需端接电阻。检查电源质量。PLL和高速SDRAM对电源噪声非常敏感。确保核心电压和I/O电压纹波在合理范围内。USB枚举失败或传输错误确认USB_REFCLKIN引脚上有24MHz或你使用的频率时钟且幅度足够。测量USB的DP/DM信号线。在USB复位期间数据线上是否有正确的差分电压时钟问题常表现为根本无USB活动。如果使用内部AUXCLK确认其频率是否是USB PHY PLL支持的频率之一12, 24, 48MHz等。以太网链路不稳定时断时续首要怀疑对象就是RMII的50MHz时钟。即使你选择了外部输入也要用示波器测量RMII_MHZ_50_CLK引脚上的时钟。频率是否精确的50.000MHz精度是否在±50ppm以内即±50Hz抖动是否过大检查PHY芯片的晶体或时钟电路。一低精度的晶体或负载电容不匹配都可能导致时钟漂移超出范围。最有效的调试工具是示波器和逻辑分析仪。不要只看软件日志一定要去测量关键时钟引脚上的实际信号。时钟问题本质上是硬件问题软件配置只是“发号施令”最终要靠物理信号来“执行”。养成上电先测时钟的好习惯能帮你节省大量无谓的代码调试时间。