MPC860 SCC缓冲区描述符与参数RAM:嵌入式通信数据流管理核心 1. MPC860 SCC缓冲区描述符与参数RAM嵌入式通信的基石在嵌入式通信处理器开发领域尤其是面对像MPC860 PowerQUICC这类集成了多个串行通信控制器SCC的复杂芯片时如何高效、可靠地管理数据流是驱动工程师的核心挑战。数据不会凭空移动它需要一个精密的“交通指挥系统”来告诉DMA控制器数据从哪里来、到哪里去、处理得怎么样了。这个系统的核心就是缓冲区描述符和参数RAM。它们不是简单的内存块而是定义了处理器与数据之间一种高效、低开销的对话机制。理解它们不仅仅是读懂手册里的几个表格更是掌握如何让硬件自动为你搬移数据从而将CPU解放出来处理更高级任务的关键。无论是实现一个稳定的以太网端口、一个可靠的HDLC链路还是一个自定义的串行协议这套机制都是你必须打通的“任督二脉”。今天我们就深入MPC860 SCC的内部拆解BD与参数RAM的每一个细节分享从手册字里行间读不出来的配置经验和调试技巧。2. 核心架构与设计思路拆解2.1 为什么需要缓冲区描述符BD在早期的嵌入式系统中处理串行数据往往采用“字节中断”模式每收到或发送一个字节就产生一个中断CPU立刻响应从寄存器中读取或写入数据。这种方式在低波特率下尚可应付但一旦速率提升巨大的中断开销会迅速吞噬CPU资源导致系统无法响应其他任务。MPC860的SCC模块采用了一种更智能的“块传输”思路其核心就是缓冲区描述符。你可以把BD想象成快递单。当你要发送一批数据包裹时你不会亲自把每个字节物品搬到串口发货站。你只需要填写一张快递单TxBD上面写明包裹内容在哪里缓冲区指针、有多少件数据长度、以及包裹当前状态已打包待发货-R位就绪。然后把这张单子交给快递员CPM通信处理器模块。快递员会根据单子信息自动从仓库内存取货并发货。同样收件时你预先准备好空箱子和对应的收货单RxBD快递员会把收到的货物放入箱子并在单子上标记“已收货、箱内件数”更新状态和长度。CPU只需要定期检查这些“快递单”的状态处理已完成的收发任务即可期间完全不需要干预具体的字节搬运过程。这种机制将CPU从繁重的I/O搬运工作中解放出来实现了高效的数据吞吐。2.2 SCC数据管理的整体蓝图MPC860的SCC模块与CPM协同工作其数据流管理涉及三层结构参数RAM这是每个SCC的“控制中心”或“配置表”。它定义了全局的运行规则比如收发BD表在内存中的起始地址RBASE, TBASE、接收缓冲区的最大长度MRBLR、以及一些内部状态指针。它在SCC初始化时设定运行时大部分参数保持不变。缓冲区描述符表这是一个由多个BD通常是8字节一个构成的数组在双口RAM中形成一个环状链表环形队列。RBASE和TBASE分别指向接收和发送BD表的开头。CPM会按照这个表中的顺序依次处理每一个BD。数据缓冲区这是实际存放收发数据的普通内存区域通常在外部SDRAM中由BD中的“缓冲区指针”字段指向。一个数据帧比如一个网络包可能很长因此可以被分割存放在多个连续的缓冲区中由多个BD串联管理。这种设计的精妙之处在于解耦和异步。参数RAM负责静态配置BD表负责动态任务调度数据缓冲区负责实际存储。CPM硬件自动循着BD表处理数据仅在需要CPU介入时如一帧收发完成、出错通过中断通知。工程师需要做的就是正确初始化这套系统然后维护好BD表的“就绪”和“空”状态形成一个顺畅的生产者-消费者管道。3. 缓冲区描述符BD的深度解析3.1 BD的结构与字段精讲每个BD固定为8字节64位其结构是SCC数据管理的原子单元。手册中的图示是概要我们需要深入每个字段的含义和操作细节。偏移 0x0状态与控制位Status and Control这是一个16位的字段是BD的“大脑”其具体含义因SCC工作的协议模式如以太网、HDLC、UART而异但有一些共通的核心位就绪位R - Ready, TxBD专用这是发送侧的“发射按钮”。当CPU准备好一个缓冲区待发送时必须将此位置1然后通过写TODR寄存器或等待CPM轮询来通知SCC。CPM发送完该缓冲区所有数据后会自动清除此位。因此驱动程序中判断一个TxBD是否发送完成就是检查其R位是否被CPM清0。这是一个关键同步点。空位E - Empty, RxBD专用这是接收侧的“空车位”指示。CPU初始化时必须将每个RxBD的E位置1表示对应的数据缓冲区是“空”的可以接收数据。当CPM接收到数据并填满或部分填充但帧结束该缓冲区后会自动清除E位。因此驱动判断是否有新数据到达就是寻找E位为0的RxBD。处理完该缓冲区数据后CPU必须重新将E位置1将其归还给CPM循环使用。回绕位W - Wrap这是BD表形成环形队列的关键。当某个BD的W位被置1时它表示这是当前BD表中的最后一个描述符。CPM处理完这个BD后其下一个BD将自动跳转到由RBASE或TBASE指向的表格起始地址。通常我们在初始化时会将BD表最后一个描述符的W位置1。连续模式CM - Continuous Mode这是一个特殊的协议相关位。当启用时CPM在处理完一个BD后不会自动清除R位或E位。这意味着一旦启动CPM会连续不断地重复使用同一个缓冲区进行发送或接收适用于某些需要持续流数据的场景。普通帧传输一般不使用此模式。错误标志位例如LG帧太长、NO非八位对齐、CRCRC错误、OV溢出、CD载波丢失、AB帧异常中止等。这些位由CPM在接收过程中根据协议规则设置是驱动进行错误统计和处理的依据。注意状态控制位是协议相关的。例如在HDLC模式下还会有TC传输CRC、RF帧结束等位。在编程时必须参考对应协议章节的BD格式定义使用正确的位掩码进行操作切忌想当然。偏移 0x2数据长度Data Length16位字段表示与此BD关联的数据缓冲区中有效数据的字节数。对于TxBD在初始化时由CPU写入你希望发送的字节数。CPM在发送过程中不会修改此字段。长度必须大于0除非协议有特殊规定。对于RxBD此字段由CPM在接收完成后写入。对于基于帧的协议如以太网、HDLC这个长度是整个帧的长度包括帧尾的CRC校验字节。这是一个极易混淆的点。如果你的驱动只处理数据 payload需要减去CRC的长度。另一个关键细节是如果接收帧的总长度含CRC恰好是MRBLR的整数倍那么最后一个BD的“数据长度”字段会记录总帧长但该BD对应的缓冲区里可能没有存放实际数据。这要求你的缓冲区管理逻辑能正确处理这种边界情况。偏移 0x4缓冲区指针Buffer Pointer32位字段指向数据缓冲区在系统内存中的起始地址。这个地址可以是内部双口RAM也可以是外部内存。对于RxBD手册要求此指针值必须偶数即地址对齐到2字节边界。这是硬件DMA的要求违反可能导致数据错误或性能下降。对于TxBD指针可以是奇数或偶数但为了最佳性能和兼容性强烈建议也按4字节或至少2字节对齐。3.2 BD表的组织与CPM工作流程BD表在内存中是连续存放的。CPM通过两个指针来管理当前进度当前BD指针在参数RAM中RBPTR和TBPTR分别指向接收和发送BD表中下一个将要被CPM使用的BD。初始化时它们被设置为RBASE和TBASE。CPM处理逻辑发送流程SCC发送器使能后CPM从TBPTR指向的TxBD开始检查。如果其R位为1则开始从该BD指向的缓冲区读取数据并发送。发送完成后CPM清除该BD的R位然后TBPTR递增指向下一个BD。如果遇到W位为1的BD则在处理完后TBPTR会绕回TBASE。CPM不会“预取”或跳过R位为0的BD它只处理当前就绪的BD。接收流程当数据到达时CPM使用RBPTR指向的RxBD其E位应为1。它将数据写入该BD指向的缓冲区直到缓冲区满达到MRBLR、一帧结束、或发生错误。然后CPM关闭该缓冲区清除E位写入数据长度并递增RBPTR。如果下一个BD的E位为0即CPU还未处理完上一个缓冲区CPM会报告“忙错误”并停止接收直到CPU将该BD的E位置1。这提供了基本的流控。实操心得BD表的“乒乓”与“链式”管理在实际驱动中我们通常初始化一组例如8个RxBD和TxBD并将最后一个BD的W位置1形成一个环。对于接收采用“乒乓缓冲区”策略中断服务程序ISR检查并处理所有E位为0的BD即已收到数据的BD处理完后立即将其E位置1放回环中供CPM再次使用。对于发送CPU准备数据后设置好BD的缓冲区指针、长度并将R位置1然后通过写SCCx的TODR寄存器或依赖CPM轮询来触发发送。关键是要确保对BD状态位的操作是原子性的特别是在多任务或中断环境中可能需要关中断或使用信号量来保护BD表的访问。4. 参数RAM的配置与实战指南参数RAM是每个SCC的私有配置区域位于双口RAM中特定的偏移地址。它包含了控制SCC数据流所必需的全局参数。4.1 关键参数详解与配置要点下表列出了所有SCC协议共用的参数RAM字段其中加粗项是必须由用户在初始化时配置的偏移量名称宽度描述与配置要点0x00RBASE半字接收BD表基地址。指向双口RAM中接收BD表起始位置的偏移量。值必须是8的倍数因为BD是8字节对齐的。0x02TBASE半字发送BD表基地址。指向双口RAM中发送BD表起始位置的偏移量。值必须是8的倍数。0x04RFCR字节接收功能代码寄存器。用于设置SDMA通道访问接收缓冲区时的总线周期属性AT[1-3]和字节序BO。0x05TFCR字节发送功能代码寄存器。用于设置SDMA通道访问发送缓冲区时的总线周期属性和字节序。0x06MRBLR半字最大接收缓冲区长度。定义了CPM一次写入一个接收缓冲区的最大字节数。这是最重要的参数之一。0x08RSTATE字接收内部状态。仅用于CPM内部用户无需操作。0x0CRIP字接收内部缓冲区指针。指向当前接收缓冲区中下一个将被写入的地址。调试时有用。0x10RBPTR半字当前接收BD指针。CPM使用它指向下一个要使用的RxBD。初始化时CPM会从RBASE加载用户通常只在禁用接收器时修改它。0x12RCOUNT半字接收内部字节计数。从MRBLR开始递减用于CPM内部计数。0x14RTEMP字接收临时寄存器。CPM内部使用。0x18TSTATE字发送内部状态。CPM内部使用。0x1CTIP字发送内部缓冲区指针。指向当前发送缓冲区中下一个将被读取的地址。调试时有用。0x20TBPTR半字当前发送BD指针。CPM使用它指向下一个要使用的TxBD。初始化时CPM会从TBASE加载用户通常只在禁用发送器时修改它。0x22TCOUNT半字发送内部字节计数。从TxBD的数据长度开始递减用于CPM内部计数。0x24TTEMP字发送临时寄存器。CPM内部使用。0x28RCRC字临时接收CRC寄存器。0x2CTCR字临时发送CRC寄存器。0x30协议特定区可变根据所选协议如HDLC、UART、以太网的不同有额外的参数需要配置。关于MRBLR的深度解析MRBLR的配置直接影响内存利用率和中断频率。设得太小如64字节会导致一个帧被分割到过多BD中增加CPM和CPU管理BD的开销中断也会更频繁。设得太大如2048字节则会浪费内存因为短帧也会占用整个缓冲区。对齐要求对于以太网和HDLC模式MRBLR必须是4的倍数。这是为了满足32位内存访问对齐以获得最佳DMA性能。对于完全透明模式除非接收FIFO宽度设置为8位否则也建议为4的倍数。动态修改手册提到MRBLR可以在运行时通过单周期16位移动指令修改但强烈不建议在接收器使能时这样做。为了精确控制修改生效于哪个RxBD必须在禁用接收器GSMR_L[ENR]0后再修改MRBLR。与缓冲区分配的关系你分配的每个接收缓冲区的大小不应小于MRBLR。通常我们直接分配大小为MRBLR的缓冲区。关于RFCR/TFCR的字节序BO设置这是一个容易出错的地方。MPC860作为PowerPC架构默认是大端序Big-Endian。如果你的数据缓冲区在内存中的布局与CPU访问的布局一致通常设置BO10大端序。如果你需要在DMA传输中自动进行字节序转换例如与一个小端序的设备通信可以设置为BO01修改的小端序。务必根据你的系统数据流需求正确配置否则会导致数据错位。4.2 SCC初始化与重配置流程手册21.4.3节给出了SCC初始化的通用步骤这里结合实战经验进行细化配置并行I/O口将对应的引脚功能设置为SCC如TXD, RXD, RTS, CTS等。这是物理连接的第一步。设置SDMA配置配置SDCR[RAID]字段设定U总线仲裁优先级。通常设置为0b01优先级5是一个合理的默认值。配置SCC全局模式寄存器GSMR这是最复杂的寄存器之一。需要设置时钟源、编码方式、数据宽度、FIFO阈值等。关键点先写入GSMR_H和GSMR_L除ENT发送使能和ENR接收使能之外的所有位。配置协议特定模式寄存器PSMR根据你使用的协议如HDLC、UART配置CRC类型、地址比较、环路模式等。配置数据同步寄存器DSR用于某些同步协议的同步模式。初始化参数RAM按照上表填写RBASE,TBASE,MRBLR,RFCR,TFCR等必须初始化的字段。同时初始化你的BD表为每个RxBD设置E1并填入缓冲区指针清零所有TxBD的状态位。清除事件与能中断向SCCE寄存器写0xFFFF以清除所有可能挂起的事件。然后向SCCM寄存器写入你想要使能的中断事件掩码。接着在CPIC层面配置中断优先级(CICR)和使能(CIMR)。最后使能SCC将GSMR_L寄存器的ENT和ENR位置1启动发送器和接收器。重配置流程例如动态改变波特率或协议你不能在SCC运行时随意更改所有参数。对于像GSMR中与DPLL、编码方式相关的位必须遵循禁用-修改-使能的流程优雅停止如果正在发送先发送GRACEFUL STOP TRANSMIT命令通过CPCR等待当前帧发送完成。禁用SCC清除GSMR_L[ENT]和/或GSMR_L[ENR]位。修改配置更新GSMR、PSMR、DSR或参数RAM中需要改变的部分。对于参数RAM需参考手册说明哪些可在运行时修改如MRBLR需在接收禁用时改。可选复位参数如果需要恢复到初始状态可以对发送或接收部分分别发送INIT TX PARAMETERS或INIT RX PARAMETERS命令。重新使能重新设置GSMR_L[ENT]和GSMR_L[ENR]。踩坑记录我曾遇到在高速HDLC通信中动态修改MRBLR后出现数据错乱的问题。原因是虽然在代码中先禁用了接收器但禁用操作与MRBLR修改指令之间可能存在指令流水线或缓存一致性问题导致CPM在某个临界时刻看到了不一致的状态。解决方案在禁用接收器后插入一个内存屏障指令如eieio确保所有对参数RAM的写操作都对CPM可见后再进行后续操作。5. 中断处理与错误排查实战5.1 SCC中断处理流程详解SCC中断是高效驱动的重要组成部分。CPM通过一个集中的中断控制器CPIC管理所有SCC的中断。你的中断服务程序ISR需要高效地处理事件并避免丢失数据。确定中断源进入ISR后首先读取SCCE寄存器。这个寄存器中的每一位对应一个特定事件如发送完成TX、发送错误TXE、接收完成RX、接收缓冲区满RXB、特殊接收条件RXF等。注意读取SCCE本身并不会清除中断标志你需要通过向该位写1来清除它写0无效。通常的做法是SCCE SCCE;即将读回的值写回去清除所有已发生的事件位。处理发送完成如果SCCE[TX]或SCCE[TXE]被置位说明一个或多个发送缓冲区已经处理完毕。你需要遍历TxBD表找到所有R位被CPM清0的BD。对于每个这样的BD意味着其关联的数据已发送完毕你可以回收这个缓冲区例如用于装载新的待发数据然后重新设置其R1如果还有数据要发或保持R0。重要由于中断延迟CPM可能已经处理了多个BD因此必须循环检查直到遇到一个R位仍为1的BD表示还未发送为止。处理接收数据如果SCCE[RX]、SCCE[RXB]或SCCE[RXF]被置位说明有新的数据到达。同样你需要遍历RxBD表找到所有E位被CPM清0的BD。对于每个这样的BD从其指向的缓冲区中读取数据长度字段指定的字节数进行数据处理。处理完毕后必须将该BD的E位置1并将其归还给CPM以供下次接收使用。同样需要循环处理直到遇到一个E位仍为1的BD。清除CPIC中断在处理完所有SCC事件后需要清除CPIC中对应的中断挂起位以允许新的中断进入。这通过向CIPR寄存器中对应的SCCx位写1来完成。中断返回执行rfi指令从中断返回。5.2 常见问题与调试技巧实录驱动开发中SCC相关的问题往往表现为数据丢失、错位、或通信完全失败。以下是一些常见陷阱和排查思路问题1数据发送不出去或接收不到。检查清单引脚复用确认并行I/O口寄存器是否正确配置将TXD/RXD等功能映射到了正确的物理引脚上。时钟与波特率检查SCC的时钟源BRG或外部CLKx是否使能且频率正确。计算波特率发生器的分频比。SCC使能位确认GSMR_L[ENT]和GSMR_L[ENR]已置1。BD状态对于发送确认TxBD的R位已置1并且通过写TODR或等待触发了CPM。对于接收确认RxBD的E位已置1。参数RAM指针检查RBASE/TBASE是否指向有效的BD表地址RBPTR/TBPTR是否指向表内。中断与轮询如果你使用中断确认CPIC和SCCM中断已正确使能。如果使用轮询确保程序在定期检查SCCE寄存器或BD状态位。问题2接收数据错位或CRC错误频繁。可能原因MRBLR与帧长不匹配如果帧长不是MRBLR的整数倍且驱动逻辑错误地假设每个BD的数据长度就是MRBLR会导致帧重组错位。务必使用BD中CPM写入的“数据长度”字段而不是假设的缓冲区长度。字节序问题检查RFCR/TFCR中的BO设置是否与你的数据内存布局匹配。如果数据从网络小端设备传来而你的CPU是大端可能需要设置修改的小端序模式或在软件中进行转换。缓冲区指针未对齐确保RxBD的缓冲区指针是偶数地址2字节对齐最好4字节对齐。时钟容差与DPLL配置在异步模式或使用DPLL恢复时钟时时钟频率容差可能过大。检查波特率设置和DPLL的采样倍数8x, 16x, 32x是否适合线路质量。问题3系统运行一段时间后通信卡死。排查方向BD表“断链”最可能的原因是驱动未能及时处理完BD并更新状态位。例如接收中断服务程序太慢未能及时将已满的RxBD的E位置1导致CPM用尽所有可用的RxBD并产生“忙错误”进而停止接收。确保ISR尽可能短平快只做必要的状态更新和数据搬运复杂处理放到任务中。内存覆盖检查BD表或数据缓冲区是否被其他代码意外写覆盖。确保这些内存区域在链接脚本中被正确分配且受到保护。中断风暴某个错误条件如时钟毛刺GLT/GLR持续产生中断而ISR未能有效清除根源导致系统忙于处理中断。检查SCCE寄存器中是否有非常规的错误位被置起。调试技巧利用内部指针当通信异常时参数RAM中的RIP接收内部指针和TIP发送内部指针非常有用。它们显示了CPM的SDMA通道下一次要访问的数据缓冲区内的地址。通过监控这些指针你可以判断DMA是否在正常工作是否卡在了某个地址。同样RBPTR和TBPTR显示了CPM当前正在使用或即将使用的BD是哪一个有助于判断BD表处理流程是否停滞。一个具体的排错案例在一次UART调试中发现只能收到第一个字符后续字符全部丢失。检查发现SCCE[RX]中断只发生了一次。排查步骤检查RxBD发现第一个BD的E位已被清0数据长度正确但第二个BD的E位仍是1。检查RBPTR发现它仍然指向第一个BD。这意味着CPM没有推进到下一个BD。原因是在初始化时我错误地将所有RxBD的数据长度字段都设为了0本应只由CPM写入。CPM在完成第一个BD后可能检查了下一个BD的某些状态虽然手册未明确说明因字段值异常而停止工作。修正在初始化RxBD时只设置E1和缓冲区指针保持数据长度字段为0。问题解决。6. 时钟、DPLL与物理层控制6.1 数字锁相环DPLL的配置与应用DPLL是SCC用于从数据流中恢复时钟的模块对于没有独立时钟线的同步通信如曼彻斯特编码至关重要。何时使当选择NRZ或NRZI编码时可以绕过DPLL选择1x模式。当选择FM0、FM1、曼彻斯特等编码时必须使用DPLL。对于UARTDPLL用于从起始位边沿开始以16倍或32倍波特率的内部时钟对数据位进行采样。时钟要求提供给DPLL的参考时钟HSRCLK/HSTCLK频率应为数据速率的8、16或32倍具体由GSMR_L[RDCR, TDCR]选择。例如对于19.2kbps的UART选择16倍采样则需要提供19.2k * 16 307.2kHz的时钟。前导码要求DPLL需要一段稳定的前导码preamble来锁定相位。手册表21-7列出了不同编码要求的最小前导码模式。例如对于NRZI Mark编码需要至少8个‘0’比特作为前导。在发送时可以通过设置GSMR_L[TPP, TPL]让SCC自动添加前导码。配置心得在调试基于DPLL的通信时如果无法锁定数据首先检查参考时钟的频率和精度是否满足要求。其次确认发送方是否发送了足够长的、正确模式的前导码。可以使用逻辑分析仪同时捕捉时钟线和数据线观察DPLL恢复出的时钟是否与数据边沿对齐。6.2 RTS/CTS/CD流控信号的时序把握对于支持硬件流控的协议如UART的CTS/RTSHDLC的CD理解GSMR中CTSS和CDS位的含义至关重要。CTSS/CDS 0采样模式。SCC在时钟的上升沿采样CTS/CD信号。这意味着CTS/CD信号需要在时钟边沿之前保持稳定一段时间满足建立时间要求。这种模式抗噪性好但响应有延迟。CTSS/CDS 1门控模式。CTS/CD信号的边沿会立即影响发送或接收。响应快但对信号毛刺敏感。在同步协议中图21-9, 21-10当RTS有效后如果CTS已经有效数据会在0比特延时后开始发送。如果RTS有效时CTS无效数据发送会等待直到CTS被采样为有效。延时约为0.5到1个比特时间。关键陷阱如果CTS被配置为“包络”数据即在帧传输期间必须持续有效那么在帧传输中间CTS失效会立即导致“CTS丢失”错误并中止发送。在设计硬件流控逻辑时必须确保CTS信号在整帧传输期间稳定。在异步协议中时序类似但起始位是第一个发送的比特。RTS有效到数据开始发送的延迟是2-3个比特时间具体取决于CTS的状态和CTSS的设置。实操建议在硬件设计阶段就要明确是否需要硬件流控并据此连接对应的引脚。在软件配置时如果不使用流控最好将对应的引脚配置为通用I/O或其他功能或将GSMR_H[CTSS/CDS]设置为无关状态并将GSMR_L[DIAG]设置为环路测试或其他非流控模式以避免意外信号导致通信阻塞。6.3 时钟毛刺检测及其意义GSMR_H[GDE]位用于使能时钟毛刺检测电路。这是一个非常有用的调试功能尤其是在原型阶段。噪声、连接器接触不良、线路反射都可能在时钟线上产生毛刺导致数据错位。当检测到毛刺时SCCE寄存器中的GLT发送时钟毛刺或GLR接收时钟毛刺位会被置位并可产生中断。建议在开发初期使能毛刺检测中断并在中断服务程序中记录毛刺事件。这可以帮助你发现潜在的硬件设计问题比如时钟线布线过长、未端接匹配电阻、电源噪声过大等。在稳定量产的产品中可以根据情况关闭此功能以节省中断开销。深入理解MPC860 SCC的缓冲区描述符和参数RAM是编写高效、稳定串行通信驱动的基石。这套机制的精髓在于将CPU从繁重的数据搬运中解脱出来通过精心设计的硬件状态机与描述符链表实现数据流的自动化管理。从正确的内存对齐到BD状态位的原子操作再到参数RAM的动态重配置禁忌每一个细节都关乎系统的稳定性和性能。调试时善用RIP、TIP等内部指针和SCCE中的错误标志能让你快速定位问题是出在硬件流控、时钟恢复还是软件侧的缓冲区管理上。记住手册是你的地图但真正的道路需要你在调试器中一步步走出来。当你看到数据通过这套复杂的机制在你的板子和远方设备间稳定流淌时你会觉得这一切的深入钻研都是值得的。