
1. 串行通信协议嵌入式系统的“血管”与“神经”在嵌入式系统的世界里处理器与外设的对话离不开串行通信协议。你可以把处理器想象成大脑而各种传感器、存储器、显示屏就是它的眼睛、耳朵和嘴巴。SPI和I2C就是连接大脑与这些器官的两套最经典、最高效的“语言”系统。它们不像并行总线那样需要一大堆线缆仅用几根线就能完成复杂的数据交换极大地简化了硬件设计降低了成本。SPI全称串行外设接口就像一场由主设备Master严格指挥的“点对点”对话。它需要四根线时钟线SCLK、主出从入数据线MOSI、主入从出数据线MISO和片选线SS/CS。主设备通过拉低某个从设备的片选线来发起对话然后在时钟的节拍下数据在MOSI和MISO上同时双向流动实现全双工高速通信。它的优势是速度快、协议简单但缺点是每个从设备都需要一根独立的片选线当设备多时引脚资源消耗大。I2C即内部集成电路总线则更像一个“多主多从”的共享电话会议。它只需要两根线串行数据线SDA和串行时钟线SCL。所有设备都挂在这两根线上每个设备都有一个唯一的7位地址。当主设备想和某个从设备通话时它先广播这个地址“呼叫”对方确认应答后再进行数据读写。I2C通过一套完善的仲裁和时钟同步机制允许多个主设备共享总线非常节省引脚但速度通常比SPI慢协议也相对复杂。在像MPC8260 PowerQUICC II这样功能强大的通信处理器中SPI和I2C控制器被高度集成并由一个独立的通信处理器模块CPM来管理。CPM通过一种称为缓冲区描述符BD的巧妙机制来卸载CPU的负担。你可以把BD理解为一个“任务工单”CPU只需要把要发送的数据地址、数据长度、操作指令等信息填进这个“工单”然后交给CPM。CPM就会自动地根据“工单”指示完成数据的搬移、发送、接收和状态报告整个过程无需CPU持续干预。这种基于BD的DMA直接内存访问机制是确保通信高效、实时响应的关键。接下来我们就深入MPC8260的内部看看如何驾驭这两个强大的控制器。2. MPC8260的SPI控制器基于BD的高速数据引擎MPC8260的SPI控制器是一个高度可配置的同步串行接口引擎。它完全由CPM管理支持主从模式最高时钟速率可达系统时钟的几分之一具体取决于分频设置并且核心的通信逻辑包括时钟生成、数据移位、片选控制都由硬件自动完成。对我们开发者而言编程的核心就是正确地初始化控制器、设置好BD表然后“下发任务”等待完成通知。2.1 SPI缓冲区描述符BD深度解析BD是CPM与CPU之间沟通的桥梁理解它的每一个字段是进行可靠编程的基础。SPI有发送BDTxBD和接收BDRxBD它们的结构类似但某些字段的含义在发送和接收场景下有所不同。我们以手册中的TxBD为例结合实战经验来拆解。一个BD通常包含三个关键部分状态与控制字段Status and Control、数据长度Data Length、缓冲区指针Buffer Pointer。状态与控制字段是一个16位的寄存器每一位都承载着特定信息。R (Ready) 位 (位0)这是最重要的控制位之一。对于TxBD当CPU准备好一个缓冲区并希望CPM发送时必须将此位置1。一旦置1CPU就不应再修改这个BD或它指向的缓冲区直到CPM完成操作后将其清零除非使用了连续模式。对于RxBD当CPU准备好一个空缓冲区用于接收数据时将R位置1在RxBD中这个位通常被称为E即Empty但原理相同。CPM在将数据填入缓冲区后会将其清零。一个常见的坑是在CPM尚未处理完当前BDR位仍为1时软件就试图修改BD或缓冲区内容这会导致数据损坏或不可预知的行为。正确的做法是通过检查R位是否被CPM清零或者等待相应的中断来确认一个BD是否可用。W (Wrap) 位 (位2)这是管理BD表一个BD数组的关键。当W位置1时表示这是当前BD表中的最后一个BD。CPM在处理完这个BD后会自动跳转到由TBASE对于TxBD或RBASE对于RxBD寄存器所指向的BD表起始地址形成环形缓冲区。这里的技巧是在初始化时我们通常只准备少数几个BD比如一对收发BD。将最后一个BD的W位置1就可以让CPM在这两个BD之间循环使用实现持续的数据流而无需CPU频繁地重新初始化BD。L (Last) 位 (位4)这个位用于指示消息边界。当发送时如果TxBD[L]被置1CPM在发送完这个缓冲区内的数据后会主动将SPI片选线SPISEL置为无效拉高从而结束本次传输事务。在从模式下这个位由CPM根据主设备是否取消片选来自动设置。它的一个重要作用是在连续发送多个数据块时只有最后一个数据块对应的BD需要将L位置1以此来告知CPM和从设备“话说完了”。如果中间某个BD错误地将L位置1会导致传输意外终止。CM (Continuous Mode) 位 (位6)连续模式是一个强大的特性但仅在主模式下有效。当CM置1时CPM在处理完这个BD后不会自动清除其R位。这意味着一旦CPM再次轮询到这个BD它会自动重复发送这个缓冲区里的数据。这个功能非常适合一些特定场景例如周期性读取一个SPI接口的ADC芯片。你只需要初始化一次BD和缓冲区填入读取ADC寄存器的命令字然后开启连续模式。CPM就会以SPI总线的最高速率不间断地向ADC发送该命令并读取结果完全无需CPU干预实现了“零开销”的自动扫描。在从模式下此位必须清零。ME (Multimaster Error) 位 (位15)多主错误标志。当SPI控制器配置为主模式时如果它检测到片选线SPISEL被外部拉低这意味着另一个主设备试图占用总线而自己正在发送数据则会触发此错误。CPM会设置ME位并关闭当前BD。这提示我们在有多处理器共享SPI总线的复杂系统中虽然SPI标准本身不是多主协议但可以通过GPIO模拟仲裁需要妥善处理总线竞争。一旦发生ME错误软件可能需要延迟重试或执行错误恢复流程。2.2 SPI主模式编程实战与避坑指南手册第38.8节给出了一个SPI主模式的初始化序列。我们不仅要知道“怎么做”更要明白“为什么这么做”以及哪里容易出错。步骤详解与原理剖析配置端口DMPC8260的SPI引脚是与其他功能复用的比如简单的GPIO或其它通信控制器。第一步就是通过端口D的引脚分配寄存器将特定引脚的功能设置为SPIMISO、SPIMOSI、SPICLK和SPISEL。这里要注意SPISEL信号有时可能需要用普通的并行I/O口来模拟以实现更灵活的片选控制尤其是当需要控制多个不在同一SPI总线上的设备时。手册步骤2提到了这一点。设置SPI参数RAM指针地址0x89FC在内部内存映射寄存器IMMR的偏移地址是一个特殊的指针寄存器用于告诉CPM到哪里去找SPI控制器的参数RAM。参数RAM里存放着RBASE、TBASE、MRBLR等关键配置。你需要将参数RAM在双端口RAM中的基地址写入这个指针。初始化参数RAMRBASE/TBASE分别指向接收和发送BD表在双端口RAM中的起始地址。端口RAM是CPM和核心CPU都能访问的一块共享内存。假设我们只用一个RxBD和一个TxBD并把他们紧挨着放在双端口RAM开头那么RBASE设为0x0000TBASE设为0x0008因为一个BD占8个字节。RFCR/TFCR功能代码寄存器通常设置为0x10表示正常操作无特殊内存访问属性。MRBLR最大接收缓冲区长度。它定义了CPM一次最多能往一个接收缓冲区里放多少字节。如果一帧数据超过这个长度CPM会关闭当前缓冲区设置BD状态并使用下一个BD如果可用。这里设置为0x0010即16字节。关键点你的接收缓冲区实际分配的内存大小必须至少等于MRBLR的值否则会导致数据溢出和内存踩踏。初始化BDRxBD状态控制字设为0xB000。我们来拆解B是二进制1011即位15未使用、位14未使用、位13未使用、位12未使用、位11未使用、位10未使用、位9未使用、位8未使用、位7未使用、位6CM0、位5保留0、位4L0、位3I0不产生中断、位2W0非最后一个BD、位1保留0、位0R/E0缓冲区初始状态为“满”或“未就绪”这里注意对于接收BD软件需要将R或E位置1表示缓冲区为空且准备就绪等待CPM填入数据。手册中0xB000的二进制是1011 0000 0000 0000位0是0这看起来像是示例中先将其置为“未就绪”可能在后续步骤再置位。更常见的做法是直接初始化为0xB000然后在启动传输前通过软件将对应BD的R位置1。数据长度可先写0缓冲区指针指向主存中预留的接收缓冲区地址如0x0000_1000。TxBD状态控制字设为0xB800。拆解B8是1011 1000相比RxBD位3I被置1了这意味着当这个BD处理完成时CPM会触发发送缓冲区事件中断如果中断被使能。数据长度设为要发送的字节数例如5。缓冲区指针指向存放了5个字节数据的主存地址如0x0000_2000。执行初始化命令向CPM命令寄存器CPCR写入0x2541_0000执行“初始化收发参数”命令。这个命令会促使CPM根据我们刚才设置的RBASE、TBASE等参数内部初始化其状态机。这是一个必须的硬件动作仅仅在内存中写好参数是不够的。配置中断与模式清除SPI事件寄存器SPIE写0xFF。设置SPI中断屏蔽寄存器SPIM为0x37使能所有可能的中断源。设置SPI模式寄存器SPMODE为0x0370。这个值决定了SPI的时钟极性、相位、主从模式、字符长度等。0x0370通常对应主模式、使能、8位字符、正常速度非回环。具体的位域需要查阅SPMODE寄存器的详细定义来精确计算。启动传输最后设置SPI命令寄存器SPCOM的启动位STR。对于主设备这会立即启动数据传输过程。避坑经验时序与缓冲区就绪确保在启动传输设置STR前你的TxBD的R位已经置1并且指向的缓冲区里已经填好了有效数据。同样对于接收至少有一个RxBD的RE位是置1的指向一个有效的空缓冲区。中断处理在中断服务程序ISR中读取SPIE寄存器确定中断源后必须通过写1来清除相应的事件位这是许多Freescale/NXP处理器常见的中断清除方式写1清0写0无效。处理完BD例如读取接收数据或重置发送BD以重用后如果需要继续传输要记得重新设置BD的R位和SPCOM的STR位。连续模式下的资源管理使用连续模式CM1时要格外小心。因为CPM会不断重复使用同一个BD和缓冲区。如果你需要更新发送的数据必须在CPM两次访问该BD的间隙时间窗口很短内完成缓冲区内容的更新否则可能读到脏数据或发送错误数据。一种更安全的做法是使用多个BD组成的环即使在一个BD处于连续发送状态时CPU也可以安全地准备下一个BD的数据。2.3 SPI从模式编程要点从模式的初始化序列与主模式高度相似主要区别在于引脚配置同样需要使能MISO、MOSI、SCLK但片选信号SPISEL是作为输入由外部主设备控制。模式寄存器SPMODE需要配置为从模式。例如手册中设置为0x0170。在从模式下波特率发生器BRG的设置通常被忽略因为时钟由外部主设备提供。传输启动在从模式下设置SPCOM[STR]并不会立即开始传输而是使能从控制器让其准备好响应主设备的片选信号。一旦主设备拉低片选并开始提供时钟从设备便自动开始收发数据。从模式下的一个关键行为手册38.9节的NOTE部分有详细描述数据传输的边界完全由主设备通过片选信号控制。例如如果主设备只发送了3个字节就释放了片选那么从设备的RxBD会关闭因为检测到消息结束但TxBD可能还保持打开如果它准备了5个字节要发送。这要求从设备端的软件必须能够处理这种“消息长度不匹配”的情况妥善关闭或重置未完成的BD。2.4 SPI中断处理流程中断是处理异步事件的高效方式。SPI中断处理的一般流程如下识别中断源进入中断服务程序后首先读取SPI事件寄存器SPIE。该寄存器的每一位代表一种事件如发送缓冲区空TXB、发送错误TXE、接收缓冲区满RXB等。清除事件通过向SPIE的相应位写1来清除事件标志。这非常重要否则会持续产生中断。处理BD对于发送完成TXB检查对应的TxBD。如果传输成功你可以重置该BD例如清零R位更新缓冲区指针和数据长度然后重新置位R位以便下次使用。如果使用了BD环则只需移动到下一个BD。对于接收完成RXB检查对应的RxBD。从BD指向的缓冲区中读取数据。然后重置该RxBD清零状态错误位更新缓冲区指针重新置位R/E位将其放回空闲池等待下一次接收。重启传输如果需要在处理完BD后如果希望继续发送或接收确保相应的BD已就绪然后可能需要再次设置SPCOM[STR]位特别是在某些单次触发模式下。中断返回执行rfi中断返回指令。3. MPC8260的I2C控制器基于仲裁的总线管家I2C控制器为MPC8260提供了标准的双线式多主从串行通信能力。与SPI的“专线专用”不同I2C是“总线共享”因此其硬件逻辑包含了地址识别、仲裁、时钟同步等更复杂的机制。3.1 I2C核心寄存器精讲与SPI类似I2C的编程也围绕几个核心寄存器展开。理解它们是编写稳定I2C驱动的前提。I2C模式寄存器I2MOD这是I2C的总开关和基础配置寄存器。EN位I2C使能位。必须在配置完其他所有参数后最后才将此位置1。在修改除EN以外的任何位时都应先确保EN0。PDIV[1:0]预分频器。它决定了输入到I2C波特率发生器BRG的时钟源BRGCLK的初始分频比。选择更大的分频值更慢的时钟可以降低功耗和噪声敏感性但需满足最终通信速率的要求。经验法则在满足性能的前提下优先选择更慢的时钟。FLT位时钟滤波使能。在电气噪声较大的环境中将此置1可以开启数字滤波器滤除SCL线上的毛刺增强通信可靠性但会引入额外的时钟延迟。REVD位数据位反转。正常情况下一个字节的最高位MSB先发送。如果某些特殊外设要求最低位LSB先发送可以设置此位。强烈建议除非外设明确要求否则保持此位为0以确保设备间的一致性。I2C地址寄存器I2ADD当MPC8260作为I2C从设备时这个7位的SAD字段就是它在总线上的“门牌号”。主设备在发起传输时会先发送这个地址来寻址它。注意I2C协议支持广播地址0x00可以通过设置I2MOD[GCD]位来选择是否响应广播呼叫。I2C波特率发生器寄存器I2BRG这是计算I2C通信速率SCL频率的关键。I2C时钟频率的计算公式相对复杂SCL频率 BRGCLK / (PDIV分频因子 * (2 * (DIV 3 (2 * FLT))))。其中DIV就是写入I2BRG寄存器的值。一个实用技巧根据所需的SCL频率如100kHz或400kHz和已知的BRGCLK频率反向推导出DIV值。注意DIV有最小值限制滤波关闭时为3开启时为6如果计算值小于最小值则无法达到那么高的SCL频率。I2C命令寄存器I2COMM/S位主从模式选择。0为从模式1为主模式。在一次通信中一个设备可以既是主也是从在多主系统中参与仲裁但需要通过软件在不同时刻切换此位。STR位启动传输位。在主模式下设置此位会令I2C控制器在总线空闲时立即产生START条件并开始发送地址帧。在从模式下设置此位是使能从设备发送器使其准备好数据一旦被主设备寻址为读操作就能立即响应。I2C事件/屏蔽寄存器I2CER/I2CMR与SPI的SPIE/SPIM类似用于管理中断。重要事件位包括RXB接收缓冲区满。一个完整的消息可能包含多个字节被接收并存放到缓冲区后此位置位。TXB发送缓冲区空。一个缓冲区的数据已全部移入发送FIFO后此位置位。注意由于I2C是双向的且有时序要求“发送完成”的真正时刻需要结合总线状态判断TXB仅表示数据已提交给硬件。TXE发送错误。当发送过程中发生无应答NACK、仲裁丢失或其它错误时此位置位。BSY总线忙。当接收到一个字符但因为无可用接收缓冲区而被丢弃时此位置位。这通常意味着软件处理速度跟不上硬件接收速度需要增加缓冲区或优化处理流程。3.2 I2C主从通信模式与实战流程I2C的通信总是由主设备发起分为写操作主写从读和读操作主读从写。3.2.1 主设备写操作Master Write这是最常用的模式例如主处理器向EEPROM写入数据或向传感器发送配置命令。软件准备主设备CPU准备好要发送的数据。第一个字节必须是7位从设备地址 写方向位R/W0。将数据填入Tx缓冲区并设置好对应的TxBDR1, L位根据是否为消息最后一个缓冲区来设置。启动传输设置I2COM[M/S]1主模式然后设置I2COM[STR]1。硬件自动执行I2C控制器检测总线空闲后产生START条件SCL高电平时SDA产生下降沿。按位发送地址帧7位地址1位写标志。从设备在第九个时钟脉冲期间拉低SDA作为应答ACK。主设备收到ACK后继续发送数据字节每个字节后从设备都应答。发送完最后一个字节后主设备产生STOP条件SCL高电平时SDA产生上升沿或重复START条件以开始下一次传输。完成与中断数据发送完毕Tx缓冲区空或发生错误无应答时触发相应中断TXB或TXE。3.2.2 主设备读操作Master Read读操作稍复杂因为它涉及传输方向的切换。软件准备主设备CPU需要准备一个特殊的Tx缓冲区。这个缓冲区的第一个字节必须是7位从设备地址 读方向位R/W1。后续的n个字节n等于你想从从设备读取的字节数内容无关紧要它们只是作为“占位符”用于在总线上产生足够的时钟脉冲来读取数据。同时必须准备好足够大小的Rx缓冲区来接收即将读回的数据。启动传输同样设置主模式并启动STR。硬件自动执行主设备发送地址帧R/W1。从设备应答后主设备立即释放SDA线从输出模式切换为输入模式从设备开始接管SDA线并发送数据。主设备在每一个字节的第八个时钟后产生一个时钟脉冲第九位并在该脉冲期间通过拉低SDA来发送应答ACK告知从设备继续发送。当主设备收到最后一个字节后它应在第九个时钟脉冲期间不拉低SDA发送NACK随后产生STOP条件通知从设备结束发送。关键点读操作中主设备发送的“占位符”数据本身不会被放到SDA线上因为方向已切换但这些数据的“发送”过程为从设备的数据输出提供了时钟。MPC8260的I2C控制器硬件会自动处理这个复杂的方向切换和时钟提供过程。3.2.3 回环测试Loopback这是一个非常有用的自检功能。将MPC8260的I2C控制器设为主模式并将其自身的从设备地址I2ADD作为目标地址进行写操作。此时主设备发送的数据会被自己的接收器收到。这无需任何特殊配置仅需在软件上将自己既作为主设备又作为寻址目标即可常用于驱动开发和硬件调试阶段验证I2C控制器硬件和底层驱动是否工作正常。3.3 I2C多主系统与软件注意事项I2C支持多主但这也带来了复杂性。MPC8260的I2C控制器在硬件上实现了仲裁当两个主设备同时发起传输时谁先发送‘0’而对方发送‘1’谁就赢得总线但软件上必须处理仲裁失败的情况。仲裁丢失处理当I2CER[TXE]错误中断产生且通过检查状态确定是仲裁丢失时软件应延迟一个随机时间后重试发送。这是标准的CSMA/CA载波侦听多路访问/冲突避免机制。操作冲突手册39.3.4节指出了一个精妙的问题假设MPC8260设备A正准备作为主设备去读取另一个设备设备C它已经设置好了读操作的TxBD里面是地址读命令。此时另一个主设备设备B突然要对设备A进行写操作。设备A的I2C控制器在作为从设备被寻址时会不假思索地将其Tx缓冲区原本准备发给设备C的读命令的数据发送出去这显然会导致通信混乱。软件协议层解决硬件无法解决这种高层逻辑冲突因此必须在应用层协议上加以规避。一个通用的最佳实践是任何I2C读操作都应遵循“先写后读”的范式。即主设备先向从设备写入一个“命令”或“寄存器地址”然后再发起读操作。许多I2C器件如EEPROM、传感器本身就要求这种操作模式。这样从设备只有在收到特定的写命令后才会在后续的读操作中准备好正确的数据避免了上述冲突。对于自主发起通信的从设备设计时应避免其主动作为主设备去读取其他未知状态的目标。4. SPI与I2C编程中的常见问题与深度排查在实际开发中通信失败是家常便饭。下面是一些基于MPC8260的典型问题排查思路很多经验也适用于其他平台。4.1 通信完全无响应检查清单电源与物理连接基础也最易忽略。确保设备供电正常上拉电阻对I2C至关重要通常4.7kΩ已正确连接线路无虚焊、短路。引脚复用配置确认你使用的SPI或I2C引脚已经通过相应的端口控制寄存器正确配置为复用功能而不是普通的GPIO。时钟使能确认CPM时钟和相应的BRGCLK已经使能。MPC8260的许多外设时钟是分模块管理的需要在系统时钟控制寄存器SCCR中打开。控制器使能SPMODE对SPI或I2MOD[EN]对I2C是否已置1必须在所有其他参数配置完成后最后才使能控制器。BD就绪状态对于发送TxBD的R位是否在启动前已置1对于接收是否有至少一个RxBD的R/E位已置1且指向有效的内存缓冲区参数RAM指针SPI参数RAM指针0x89FC或I2C参数RAM指针0x8AFC是否已正确指向双端口RAM中已初始化的参数表区域4.2 数据错误或丢失SPI特定问题时钟极性与相位CPOL/CPHA不匹配这是SPI通信中最常见的错误。主从设备的SPI模式必须完全一致模式0123。检查SPMODE寄存器中关于时钟极性和相位的位域设置确保与从设备数据手册要求一致。一个快速调试方法是使用示波器同时观察SCLK、MOSI和片选线对照从设备时序图逐一比对。片选信号异常确认片选信号在传输期间保持有效低电平并在传输结束后及时无效高电平。如果使用软件GPIO模拟片选要确保时序严格在SCLK稳定前拉低在最后一个时钟沿后拉高。缓冲区溢出/下溢接收时如果数据涌入速度超过CPU处理BD的速度会导致缓冲区用尽后续数据丢失可能触发RxBD[OV]标志。发送时如果CPU填充数据速度跟不上发送速度会导致发送FIFO空产生下溢可能触发TxBD[UN]标志仅在从模式。解决方法是增加BD环的长度或优化中断服务程序效率。I2C特定问题从设备无应答NACK首先用逻辑分析仪抓取波形看主设备发送的7位地址是否正确。地址通常包含一个固定的器件类型码和由硬件引脚决定的几位可编程地址。确保地址计算正确且从设备已上电并正常工作。时钟速率过快I2C总线有电容负载限制。总线上的设备越多走线越长等效电容越大信号上升沿越慢。过快的SCL速率会导致建立/保持时间不满足通信失败。尝试降低I2BRG的DIV值将速率降到100kHz甚至更低进行测试。仲裁失败与总线锁死在多主系统中如果一个主设备在传输中途异常复位或崩溃可能会将SDA线拉低且不释放导致整个总线锁死。一些I2C器件具有超时复位功能但并非所有。硬件上可以在SDA/SCL线上增加一个由MCU控制的弱上拉三极管在检测到总线长时间低电平时强制复位上拉。软件上主设备在发起传输前应持续监测总线空闲状态SDA和SCL均为高一段时间。4.3 中断不触发或频繁触发中断未使能检查SPIMSPI或I2CMRI2C寄存器是否已经使能了你所关心的事件如TXB, RXB的中断。同时确保处理器核心层面的中断控制器也已使能该中断源。中断标志未清除这是导致中断只触发一次或进入错误中断状态循环的常见原因。必须在中断服务程序ISR中读取事件寄存器SPIE/I2CER后通过写1的方式清除对应的位。忘记清除标志位中断会一直处于挂起状态。BD状态未更新对于发送完成中断TXB在ISR中处理完旧的TxBD后如果没有将其R位清零并重新置1或链接到下一个就绪的BD那么CPM会认为没有新的数据可发可能不会再次触发TXB中断。对于接收处理完一个满的RxBD后必须将其重置为空R/E1状态CPM才能继续使用它接收数据。4.4 性能优化技巧使用BD环不要只使用一对收发BD。初始化一个由多个BD如4个或8个组成的环形链表通过设置最后一个BD的W1来实现环。这样CPM可以连续处理多个缓冲区而CPU可以在后台准备后续缓冲区的数据实现“流水线”操作极大提高吞吐量避免因软件处理延迟导致的数据丢失。合理设置MRBLR对于SPI和I2C的接收MRBLR定义了每个接收缓冲区的最大容量。设置过小会导致频繁的缓冲区关闭和中断增加CPU开销。设置过大则会增加单次中断的处理延迟并可能浪费内存。一个折中的办法是将其设置为一次典型通信事务的数据量或者略大于此值。DMA与CPU缓存一致性MPC8260的CPM通过SDMA通道直接访问主存。如果你的CPU有数据缓存Cache并且BD结构或数据缓冲区位于可缓存的内存区域你必须确保缓存一致性。在CPU更新了BD或缓冲区数据后在启动DMA传输前需要执行缓存写回Write-Back或无效Invalidate操作。否则CPM可能读到的是缓存中的旧数据或者CPU可能从缓存中读到CPM刚更新但还未写回内存的旧数据。这是嵌入式系统开发中一个非常隐蔽但致命的错误来源。通常需要调用特定的底层库函数或操作缓存控制寄存器来处理。