1. 项目概述为什么我们需要深入理解PRCM寄存器在嵌入式开发尤其是汽车电子和工业控制这类高可靠性领域里摸爬滚打十几年我越来越觉得能把芯片“伺候”好是项目成功的一半。这里的“伺候”指的就是电源、复位和时钟管理。很多工程师特别是刚入行的朋友往往把精力都花在应用逻辑和算法上觉得底层硬件配置是芯片厂商或BSP包该搞定的事照着例程配一下就行。但真到了调试阶段系统莫名死机、外设工作异常、功耗居高不下或者EMC测试怎么也过不去的时候回头一查十有八九问题就出在电源、复位和时钟的配置上。TI的16xx系列芯片作为广泛应用于车身控制、网关、电机驱动等场景的微控制器其PRCM模块设计得非常复杂和强大。它绝不仅仅是上电后给个时钟那么简单。整个模块像是一个精密的交响乐团指挥需要协调内核、多个总线、数十个外设的上下电时序、复位释放顺序以及时钟频率/源的选择。而指挥棒就是那一组组映射在内存空间的控制寄存器。你提供的资料正是这个“指挥总谱”中最核心的几页。这次我们不满足于只看手册里的寄存器位域描述。我将结合多年的调试经验把这些零散的寄存器信息串联起来拆解其背后的设计逻辑、实操中的配置步骤以及那些手册里不会写的“坑”。我们会重点探讨共享内存分配、PBIST测试时钟、以及MSS_RCM主子系统复位与时钟管理这几个关键部分。目标是让你看完后不仅能看懂这些寄存器更能理解在什么场景下、为什么要这样配置从而在自家项目中游刃有余。2. 核心设计思路PRCM模块的架构与协同逻辑在深入每个寄存器之前我们必须先建立顶层视图。TI 16xx的PRCM模块其核心设计思路是分层、分区、分权管理。分层体现在通常芯片会有整个芯片级的电源/复位控制如PSC和各个子系统如MSS主子系统、DSS协处理器子系统内部的时钟/复位管理。你资料中提到的MSS_RCM就属于主子系统这一层。分区体现在不同功能模块的时钟和复位可能是独立的。例如给CAN FD模块的时钟FDCANCLK和给QSPI Flash控制器的时钟QSPICLK来源和分频可以单独设置这为实现精细功耗管理和满足不同外设的时序要求提供了可能。分权体现在对关键寄存器的写操作往往需要“钥匙”Kicker比如KEY寄存器Offset ACh需要写入特定的0x83E783E7才能解锁对MSS_RCM其他寄存器的写操作。这是一种安全机制防止软件跑飞后意外修改关键配置。从你提供的寄存器列表看其管理范畴可以归纳为以下几类共享资源分配如SHMEMBANKSEL3TO0和SHMEMBANKSEL7TO4负责将片内共享RAM的各个Bank分配给不同的主机DSS, MSS, BSS等这是多核/多主系统内存隔离的基础。时钟生成与门控这是大头包括时钟源选择CLKSRCSEL0,CLKSRCSEL1,PBISTCLKCTL.PBIST300MCLKSRCSEL等寄存器用于为各个时钟域选择源头如CPUCLK, RCCLK, PLL分频时钟等。时钟分频CLKDIVCTL0,PBISTCLKCTL.PBIST300MCLKDIV等用于对选中的时钟源进行分频得到最终的工作频率。时钟门控CLKGATE寄存器用于在逻辑上开关时钟是动态功耗管理的关键手段。当前分频值读取CURRCLKDIV0,CURRCLKDIV1等只读寄存器用于验证或监控当前的时钟配置状态。复位控制SOFTRST1,SOFTRST2用于对特定模块如CR4内核、VIM中断控制器进行软件复位。存储器初始化与ECCMEMINITSTART/MEMINITDONE用于触发和控制各块RAM的硬件初始化ECCENMSSGEM,SECURERAMECC等用于启用和监控存储器的ECC错误校验与纠正功能这对功能安全应用至关重要。杂项控制与状态如USERMODEEN用于切换访问模式SWIRQA/B用于软件触发中断RSTCAUSE用于查询上次复位原因ESMGATE系列寄存器用于配置错误信令模块等。理解这个架构后我们再去看每个寄存器就不再是孤立的位域而是知道它在整个管理系统中的角色和上下游关系。3. 关键寄存器深度解析与实操要点3.1 共享内存分配寄存器SHMEMBANKSELx这是理解芯片多主架构内存视图的第一课。SHMEMBANKSEL3TO0和SHMEMBANKSEL7TO4这两个寄存器控制着共享内存Shared RAM8个BankBank0-Bank7的归属。寄存器逻辑解析位域每个寄存器管理4个Bank。每个Bank由一个8位的字段控制例如BANK0位[7:0]、BANK1位[15:8]等。编码含义向该8位字段写入特定值代表将该Bank分配给某个“主设备”Master。0x01: DSS (可能是数字信号子系统或类似主设备)0x02: MSS TCMA (主子系统TCM A)0x04: MSS TCMB (主子系统TCM B)0x08: OCLA (可能是一个跟踪或分析模块)0x10: BSS TCMA (可能是另一个子系统的TCM A)一个极其关键的细节在SHMEMBANKSEL3TO0的描述中对于BANK3到BANK0它明确写着“only valid value is 0x1 else memory is not used. (Allocation only to DSS L3RAM)”。这意味着Bank0-3只能分配给DSS写其他值会导致该Bank无法被使用而SHMEMBANKSEL7TO4的描述则显示Bank4-7可以分配给更多的主设备DSS, MSS TCMA/B, OCLA, BSS TCMA。实操要点与避坑指南初始化时机这类资源配置寄存器必须在所有可能访问该共享内存的主设备启动之前完成配置。通常放在系统初始化非常靠前的阶段在使能缓存、DMA等操作之前。配置一致性必须确保所有主设备对共享内存的映射视图是一致的。例如如果MSS配置了Bank5归自己而DSS也试图去配置Bank5归自己就会导致冲突和不可预知的行为。通常由某一个核心如MSS进行统一配置。默认值非安全复位后这些寄存器可能有默认值如0x01010101但这不一定是你的应用所需的安全或最优配置。绝不能依赖默认值必须根据你的系统设计显式配置。内存隔离与安全在功能安全ISO 26262系统中通过合理分配Bank可以实现内存空间的隔离防止非授权访问这是构成安全岛Safety Island的基础之一。配置示例伪代码// 假设我们需要将 Bank0-3 给DSS Bank4 给MSS TCMA Bank5 给MSS TCMB Bank6-7 保留或给其他主设备 volatile uint32_t *SHMEMBANKSEL3TO0 (volatile uint32_t*)0xFFFFE2C8; volatile uint32_t *SHMEMBANKSEL7TO4 (volatile uint32_t*)0xFFFFE2CC; // 配置 Bank0-3 为 DSS (0x01) // 每个Bank占8位所以值 (0x01 24) | (0x01 16) | (0x01 8) | 0x01 *SHMEMBANKSEL3TO0 0x01010101; // 注意此默认值恰好是复位值但我们必须显式写入 // 配置 Bank4-7: Bank4-MSS TCMA(0x02), Bank5-MSS TCMB(0x04), Bank6-保留(可设0x01给DSS或保持) Bank7-保留 // 计算: Bank70x01, Bank60x01, Bank50x04, Bank40x02 // 即: (0x01 24) | (0x01 16) | (0x04 8) | 0x02 0x01010402 *SHMEMBANKSEL7TO4 0x01010402;3.2 PBIST时钟控制寄存器PBISTCLKCTLPBISTProcessor Built-In Self-Test是芯片内部用于自测试的逻辑其时钟需要独立配置。PBISTCLKCTL寄存器虽然看起来只控制一个测试模块的时钟但其设计思想具有代表性。寄存器逻辑解析PBIST300MCLKGATE(位[15:8])时钟门控。手册说明“to gate the clock either 3:0 should be 0xD or 7:4 should be 0xA”。这是一个安全使能模式需要向特定的半字节写入特定值才能开关时钟防止意外写操作。例如要关断时钟需要向该字段写入0xAD即高4位是A低4位是D。PBIST300MCLKSRCSEL(位[7:4])时钟源选择。可选源包括CPUCLK、RCCLK、600MHz PLL分频时钟、外部参考时钟等。不同的源对应不同的频率和稳定性。PBIST300MCLKDIV(位[3:0])分频值。从1分频0000到15分频1111。一个至关重要的操作顺序提示在描述PBIST300MCLKDIV时手册明确警告“One Should change the divide value before switching to New clock. Switching to New clock is done by programming PBIST300MCLKSRCSEL”。必须先配置分频再切换时钟源如果顺序颠倒在切换到一个高频源时如果分频器还是默认的除1可能会导致后续电路无法承受过高的频率而工作异常。实操要点与避坑指南配置顺序铁律对于任何有时钟源选择CLKSRCSEL和分频CLKDIV的模块都必须遵守“先分频后换源”的原则。这是一个通用准则。门控的使用在切换时钟源或进行大幅度频率调整前可以考虑先门控Gate该时钟待配置稳定后再打开。但这需要结合具体模块的时序要求有些模块不允许时钟长时间关闭。频率匹配选择时钟源和分频时必须确保最终生成的时钟频率在模块允许的工作范围内。例如PBIST模块可能要求时钟不超过300MHz。功耗考虑PBIST通常只在生产测试或特定诊断时使用。在正常应用运行时应将其时钟门控以节省功耗。配置示例假设需要将PBIST时钟配置为来自600MHz PLL并10分频得到60MHzvolatile uint32_t *PBISTCLKCTL (volatile uint32_t*)0xFFFFE2D0; uint32_t reg_val; // 1. 读取当前值可选但好习惯 reg_val *PBISTCLKCTL; // 2. 配置分频值10分频。手册说“0000”div1, “0001”div2... 所以10分频对应值应为 9 (0x9)。 // 清除原来的分频位[3:0] reg_val ~(0xF); // 设置新的分频值 reg_val | (0x9 0xF); // 设置分频为10 // 3. 可选如果需要先门控时钟。向门控字段[15:8]写入0xAD reg_val ~(0xFF00); // 清除门控字段 reg_val | (0xAD 8); // 门控时钟 // 4. 写回寄存器应用分频和门控设置 *PBISTCLKCTL reg_val; // 5. 配置时钟源选择600MHz PLL分频时钟对应值010即0x2 reg_val ~(0xF0); // 清除源选择位[7:4] reg_val | (0x2 4); // 设置时钟源 // 6. 如果之前门控了解除门控。向门控字段写入非0xAD的值例如0x00。 reg_val ~(0xFF00); // 清除门控字段 // reg_val | (0x00 8); // 已经是0可省略 // 7. 写回寄存器完成时钟源切换和打开门控 *PBISTCLKCTL reg_val;3.3 MSS_RCM 关键寄存器组详解MSS_RCM是主子系统复位与时钟管理的核心。你提供的列表包含了从SOFTRST1到SWIRQC的数十个寄存器。我们挑几个最典型、最容易出问题的来讲。3.3.1 软件复位寄存器SOFTRST1/2这两个寄存器用于对特定模块进行“热复位”而不影响整个芯片。SOFTRST1.CR4SYSRST复位MSS的CR4内核。注意其触发机制手册描述“reset will happen either lower 4 bit is 0XD or Upper four bit is 0xA”。这意味着要向这个8位字段写入0xAD高4位是A低4位是D才能触发复位。这也是一个安全写机制。复位操作是“Self clearing”的即硬件会自动清除该字段。SOFTRST2.VIMRST复位VIM向量中断管理器。触发机制同上写入0xAD。实操要点使用场景当某个内核或模块如VIM出现软件死锁或状态异常时可以通过此寄存器对其进行局部复位恢复功能避免整个系统重启。操作后等待发起软件复位后必须等待足够的时间通常需要查询该模块的状态寄存器或等待固定的延迟确保复位完成且模块稳定后才能重新对其进行初始化配置。副作用复位该模块会清除其内部状态和寄存器所有正在进行的操作都会中止。需要软件重新初始化该模块。3.3.2 时钟源选择与分频寄存器CLKSRCSEL0/1 与 CLKDIVCTL0这是配置外设时钟的核心。以CLKSRCSEL0和CLKDIVCTL0为例它们共同控制着FDCAN、QSPI、RTI等外设的时钟。CLKSRCSEL0包含FDCANCLKSRCSEL、QSPICLKSRCSEL、RTICCLKSRCSEL、RTIDCLKSRCSEL等多个字段每个字段4位用于选择对应外设的时钟源。源选项通常包括VCLK系统主时钟、RCCLK低速参考时钟、不同PLL的分频输出、CPUCLK以及来自模拟部分的REFCLK。CLKDIVCTL0包含FDCANCLKDIV和VCLKCLKDIV等字段每个字段8位提供最多256分频。注意VCLKCLKDIV在CLKDIVCTL0里但其源选择VCLKCLKSRCSEL却在CLKSRCSEL1寄存器里。配置时必须配对使用。配置流程与计算示例以配置FDCAN时钟为例 假设我们需要FDCAN模块工作在40MHz。可用的时钟源有VCLK 200MHz600MHz PLL分频时钟 300MHz (假设已配置为除以2)REFCLK 40MHz (来自外部晶振)方案选择选择REFCLK (40MHz)分频设为1。最简单直接精度取决于外部晶振。选择VCLK (200MHz)分频设为5 (200/540MHz)。更灵活但分频可能引入抖动。选择600MHz PLL分频时钟(300MHz)分频设为7.5不行分频器是整数300/742.85MHz不精确。我们选择方案1使用REFCLK。volatile uint32_t *CLKSRCSEL0 (volatile uint32_t*)0xFFFFE01C; // 假设基址偏移计算后得到 volatile uint32_t *CLKDIVCTL0 (volatile uint32_t*)0xFFFFE018; uint32_t srcsel_val, divctl_val; // 1. 配置分频器 (先分频) divctl_val *CLKDIVCTL0; // 清除FDCAN分频字段位[31:24] divctl_val ~(0xFF 24); // 设置分频值为1 (对应0x00) // divctl_val | (0x00 24); // 因为清零后就是0代表div1所以这步可省略 *CLKDIVCTL0 divctl_val; // 2. 配置时钟源 srcsel_val *CLKSRCSEL0; // 清除FDCAN时钟源选择字段位[11:8] srcsel_val ~(0xF 8); // 设置时钟源为 REFCLK from ANA根据手册编码为 110 (0x6) srcsel_val | (0x6 8); *CLKSRCSEL0 srcsel_val;3.3.3 存储器初始化寄存器MEMINITSTART 与 MEMINITDONE在系统上电或从低功耗模式唤醒后片内RAM的内容是随机的可能包含ECC错误。硬件初始化Hardware Memory Initialization会用确定的值通常是0填充RAM并初始化ECC状态。这对于功能安全和系统稳定性至关重要。MEMINITSTART触发寄存器。其最高字节MEMINITKEY需要先写入0xAD来使能整个初始化功能。然后通过写1到各个具体的存储器位如CR4TCMAMEM,VIMMEM,DMAMEM等来触发对应存储器的初始化。该位是“Self clearing”的。MEMINITDONE状态寄存器。对应的位为1时表示该存储器的硬件初始化已完成。实操流程与避坑指南顺序性必须先写MEMINITKEY再触发具体存储器的初始化。通常的操作是MEMINITSTART (0xAD 24) | (1 target_mem_bit)。轮询等待触发初始化后必须轮询MEMINITDONE寄存器中对应位直到其变为1才能认为该存储器可用。绝对不能在初始化完成前访问该存储器批量操作可以一次性设置MEMINITSTART的多个位来触发多个存储器的并行初始化然后轮询MEMINITDONE中所有对应位。应用场景不仅在上电复位后需要在从某些深度低功耗模式如Standby唤醒后由于RAM数据可能丢失或损坏也需要重新初始化。配置示例初始化MSS的TCMA和TCMBvolatile uint32_t *MEMINITSTART (volatile uint32_t*)0xFFFFE05C; volatile uint32_t *MEMINITDONE (volatile uint32_t*)0xFFFFE06C; // 1. 使能初始化功能并触发TCMA和TCMB初始化 // MEMINITKEY 0xAD (位[31:24]), CR4TCMAMEM 位0, CR4TCMBMEM 位1 *MEMINITSTART (0xAD 24) | (1 1) | (1 0); // 2. 轮询等待初始化完成 while (((*MEMINITDONE) ((1 1) | (1 0))) ! ((1 1) | (1 0))) { // 等待可以加入超时机制 } // 3. 初始化完成现在可以安全地使用CR4 TCMA和TCMB了3.3.4 用户模式访问使能寄存器USERMODEEN 与 KEY这是安全性和访问权限控制的体现。MSS_RCM中的许多寄存器是系统关键寄存器默认可能只允许在特权模式如Supervisor Mode下访问。KEY寄存器解锁钥匙。需要先向KEY寄存器写入特定的魔法数字0x83E783E7才能解锁对MSS_RCM空间其他寄存器的写操作。USERMODEEN寄存器向该寄存器写入0xADADADAD将使能用户模式User Mode对MSS_RCM空间的写访问。实操要点典型启动流程在特权模式下先写KEY解锁然后进行所有必要的PRCM配置时钟、复位、内存初始化等。配置完成后可以选择性地写USERMODEEN以在用户模式下也能修改某些设置但通常出于系统安全考虑不建议这样做。更常见的做法是在完成所有关键配置后不再写KEY从而锁住这些寄存器防止应用程序意外修改。错误配置的风险如果错误地在用户模式下尝试写未使能的寄存器可能会导致总线错误Bus Fault或访问权限错误。4. 系统初始化流程中的PRCM配置实战理解了单个寄存器后我们将其串联起来看一个简化的系统上电初始化流程中PRCM相关部分应该如何操作。这比看TI的启动代码更贴近我们自己的理解。阶段一从复位向量开始最低层配置初始化栈指针和关键变量汇编/C启动代码。配置时钟源和PLL可能涉及更底层的PLL控制寄存器不在你提供的列表中。等待PLL锁定。解锁MSS_RCM如果需要KEY 0x83E783E7。配置主系统时钟VCLK通过CLKSRCSEL1.VCLKCLKSRCSEL选择时钟源如切换到PLL输出并通过CLKDIVCTL0.VCLKCLKDIV设置分频得到最终的系统主频。记住先分频后切源。初始化关键存储器使用MEMINITSTART和MEMINITDONE对CR4的TCM、VIM、DMA等关键RAM进行硬件初始化。确保在访问它们之前完成。阶段二外设时钟与基础服务6.配置外设时钟根据应用需求依次配置CLKSRCSEL0和CLKDIVCTL0为FDCAN、QSPI、RTI等外设分配合适的时钟源和频率。例如CAN总线需要精确的时钟来保证波特率。 7.配置共享内存根据系统架构配置SHMEMBANKSEL3TO0和SHMEMBANKSEL7TO4划分好各主设备对共享RAM的访问权限。 8.使能ECC如果应用需要对于用于安全通信的邮箱内存如MSS-GEM, BSS-GEM或安全密钥RAM通过ECCENMSSGEM、ECCENBSSGEM、SECURERAMECC等寄存器使能ECC功能以检测和纠正内存位错误。 9.配置软件中断如果需要设置SWIRQA、SWIRQB等用于多核间或任务间的软件触发中断通信。阶段三外设模块使能与应用启动10.解除外设时钟门控在CLKGATE寄存器中将RTICCLKGATE、FDCANCLKGATE、QSPICLKGATE等位清零让时钟信号进入外设模块。 11.释放外设复位如果某些外设有独立的软复位控制可能在别的模块在此处执行。 12.初始化外设驱动此时外设的时钟和复位都已就绪可以开始调用标准的外设驱动初始化函数如CAN_init(),SPI_init()。 13.锁住关键配置可选停止向KEY寄存器写入解锁值防止后续代码误操作PRCM寄存器。 14.跳转到主应用或操作系统。这个流程是一个逻辑框架具体顺序和步骤需要根据具体的16xx型号、参考手册和你的板级支持包来调整。但它清晰地展示了PRCM配置在启动序列中的核心位置和逻辑依赖关系。5. 调试排错与常见问题实录即使按照手册配置在实际项目中依然会遇到各种问题。下面分享几个我踩过的“坑”和排查思路。问题一系统运行不稳定偶发死机尤其是在访问某些外设或特定内存区域时。排查思路检查时钟配置首先怀疑时钟。用示波器或逻辑分析仪测量相关外设的时钟引脚如果引出看频率是否与配置相符波形是否干净。如果没有测量点就读取CURRCLKDIV0、CURRCLKDIV1等只读寄存器验证当前分频值是否正确。检查共享内存配置死机如果发生在多核通信或DMA传输时重点检查SHMEMBANKSEL寄存器。确认所有参与访问的主设备对同一块内存的配置是否一致。冲突的配置会导致访问失败或数据损坏。检查存储器初始化如果死机发生在启动早期访问TCM或特定RAM时检查MEMINITDONE状态。确认在访问前对应的内存初始化确实已经完成。我曾遇到过因为忘记等待MEMINITDONE导致CRC校验失败而反复重启的问题。检查复位状态查询RSTCAUSE寄存器了解上次复位的原因。是上电复位、看门狗复位、还是软件复位这能提供重要线索。问题二外设如CAN通信波特率不准或根本无法通信。排查思路确认时钟源和分频计算这是最常见的原因。仔细计算CLKSRCSEL选择的时钟源频率以及CLKDIV设置的分频比。例如你为FDCAN选择了VCLK200MHz分频值设为0x0910分频期望得到20MHz的FDCAN基础时钟。但实际测量发现是22.2MHz。一查发现VCLK的实际运行频率是222MHz而不是你以为的200MHz。教训永远不要假设时钟频率要用工具确认或读取相关状态寄存器。检查时钟门控外设的时钟是否被CLKGATE寄存器给关掉了确保对应位是0开启。遵循配置顺序是否违反了“先分频后换源”的铁律在切换到一个高频率时钟源时如果分频器还是大的分频值可能导致瞬间频率过低反之如果分频器是1切换高频源可能导致后级电路过冲。严格按照顺序操作。问题三尝试配置PRCM寄存器但写操作无效值读回来没变。排查思路访问权限当前CPU是否处于特权模式USERMODEEN是否已正确使能如果需要在用户模式写更常见的是是否忘记了写KEY寄存器来解锁第一个要检查的就是KEY寄存器有没有写对0x83E783E7。寄存器偏移地址确认你使用的基地址和偏移量是正确的。不同芯片型号、不同内存视图如调试视图与运行视图下这些寄存器的绝对地址可能不同。位域操作错误在C语言中对寄存器进行“读-改-写”操作时要确保读-写的是同一个物理地址并且没有受到编译器优化或缓存的影响。通常将寄存器指针声明为volatile。在修改部分位时注意清除和设置的掩码要准确。问题四系统功耗高于预期。排查思路时钟门控检查CLKGATE和类似PBISTCLKCTL.PBIST300MCLKGATE的寄存器。所有不使用的模块时钟都应该被门控。例如如果没用QSPI就把QSPICLKGATE置1。外设时钟频率在满足性能要求的前提下是否可以为某些外设选择更低频率的时钟源或设置更大的分频降低频率是减少动态功耗的有效手段。模块软复位对于完全不使用的模块除了关时钟还可以考虑使用SOFTRST将其保持在复位状态进一步降低功耗。通用调试技巧寄存器地图为自己维护一份关键寄存器的地址和复位值表格调试时方便对照。版本差异注意你提供的资料日期是2020年6月。务必确认你使用的芯片型号和硅片版本Revision与手册完全对应。不同版本间寄存器定义可能有细微差别。利用只读状态寄存器CURRCLKDIVx、MEMINITDONE、RSTCAUSE、ECCCAPTx等都是宝贵的调试信息源在出现问题时应首先读取它们来分析状态。6. 高级话题ECC功能配置与安全考虑在汽车和工业应用中ECC不再是可选项而是必选项。你资料中的ECCENxxx和ECCCAPTx寄存器就是用于管理存储器ECC的。使能ECC通过向ECCENMSSGEM、ECCENBSSGEM、SECURERAMECC.SECURERAMECCEN等寄存器的特定字段写入0xAD来使能对应存储体的ECC功能。必须在存储器初始化完成之后并在任何数据写入之前使能ECC。错误捕获与清除当ECC检测到错误时错误地址和修复的位信息会被捕获到ECCCAPTMSSGEM等寄存器中。软件可以定期轮询或通过中断来读取这些寄存器进行错误记录和诊断。读取后需要向ECCENxxx寄存器中的清除位字段如描述中的18:16,21:19位写入3‘b111来清除捕获的地址以便捕获下一次错误。安全关键性对于安全相关的数据如密钥、安全状态变量必须存放在具有ECC保护的内存中并且软件需要实现错误处理机制如错误计数、达到阈值触发安全状态转换。配置ECC的代码需要非常小心确保使能和清除操作的顺序正确并且错误处理路径得到了充分测试。最后我想强调的是PRCM的配置是嵌入式系统底层的基石。它枯燥、繁琐但至关重要。花时间彻底理解你项目中用到的每一个PRCM寄存器尤其是在系统调试初期这能为你节省大量后期追查诡异问题的时间。最好的学习方式就是结合芯片数据手册、参考手册和实际的板子写一些小的测试程序通过调试器去观察修改寄存器后系统的变化。当你能够自如地掌控芯片的脉搏时钟和呼吸电源/复位时你才真正成为了这片硅晶圆的主人。