1. 项目概述:当经典协议遇上硬件加速
在嵌入式系统,尤其是工业控制、金融终端或传统专网通信设备的设计中,我们常常需要与一些“古老”但极其可靠的通信协议打交道。BISYNC(Binary Synchronous Communication,二进制同步通信)协议就是其中之一。它诞生于上个世纪,是一种面向字符的同步数据链路控制协议,其核心思想是通过预定义的、像“交通信号灯”一样的控制字符(如SOH、STX、ETX、ENQ)来组织数据帧,实现同步、差错校验和流量控制。对于现代高性能嵌入式处理器而言,用软件逐字节解析这些控制字符并管理数据缓冲区,无疑会消耗大量宝贵的CPU周期,成为系统吞吐量的瓶颈。
MPC8560 PowerQUICC III处理器提供了一种优雅的解决方案:其串行通信控制器(SCC)模块内置了对BISYNC协议的硬件支持。这不仅仅是简单的UART加上一些固件库,而是将协议解析的核心逻辑——特别是控制字符的识别与帧边界判定——下沉到了专用的通信处理器(CP)中,并与DMA引擎深度集成。这意味着,一旦配置妥当,数据流的接收、控制字符的匹配、帧的自动分割、乃至块校验序列(BCS,即CRC或LRC)的计算与验证,都可以在后台自动完成,仅在整个数据块就绪或发生特定事件时,才通过中断通知主CPU。这种硬件加速机制,对于需要维持高数据完整性同时又要保证低延迟响应的系统来说,是至关重要的性能保障。本文将深入拆解MPC8560 SCC的BISYNC模式,特别是其控制字符识别与DMA通信的协同工作机制,为你呈现从寄存器配置到缓冲区管理的完整实战图景。
2. BISYNC模式核心机制解析
要驾驭MPC8560的SCC BISYNC模式,不能仅仅停留在配置步骤的层面,必须理解其硬件设计哲学。其核心目标是将软件从繁琐的、重复性的协议解析劳动中解放出来。为了实现这一点,硬件提供了几个关键机制:一个可编程的控制字符识别表,用于自动判定帧结束;一套与DMA紧密耦合的缓冲区描述符(BD)体系,用于高效的数据搬运;以及一系列模式寄存器,用于精细控制收发行为。这些机制共同构成了一个半自动化的协议处理流水线。
2.1 控制字符识别表:硬件的“协议词典”
这是BISYNC模式的“大脑”。它本质上是一个由用户预定义的小型查询表,SCC的硬件逻辑会拿接收到的每一个字节与表中的条目进行比对。这张表位于SCC的寄存器地址空间,从SCCx_BASE + 0x42开始,共8个条目,每个条目16位。
每个条目的结构非常精妙,远不止存储一个字符那么简单:
- 字符值(CHARACTERn, 位8-15):这就是你要匹配的控制字符,例如ETX(0x03)。注意,如果协议使用7位数据加1位奇偶校验,这个值需要包含校验位。
- 结束位(E, 位0):这是一个“表结束”标志。当硬件扫描到此条目且E=1时,会停止继续向下匹配。这允许你定义少于8个的有效字符。通常,在配置了所有需要的字符后,将下一个条目的E置1。
- BCS期望位(B, 位1):这是最关键的一位。当匹配到该字符时,若B=1,则硬件认为当前数据块结束,并且期望后面紧跟一个块校验序列(BCS,即CRC或LRC)。硬件会自动进入“等待BCS”状态,接收后续的1个(LRC)或2个(CRC)字节,并将其纳入校验计算,最后关闭缓冲区。这对于ETX、ETB这类标识正文结束并附带校验的字符是必须的。
- 搜索模式位(H, 位2):匹配成功后,若H=1,接收器将进入“搜索模式”(Hunt Mode)。在此模式下,接收器会丢弃所有接收到的数据,直到重新捕获到同步字符(SYNC)。这通常用于帧间间隔或线路空闲时重新同步。像ETX这种标志一个完整帧结束的字符,通常需要置位H,以便为接收下一帧做好准备。
举个例子:假设你的协议规定ETX(0x03)表示正文结束且后跟CRC,帧结束后接收机需要重新同步。那么你需要将CHARACTER1寄存器设置为0x6003(二进制0110 0000 0000 0011)。这里,E=0(条目有效),B=1(期望BCS),H=1(进入搜索模式),字符值为0x03。
RCCM寄存器:这是一个8位的掩码寄存器(位于0x52地址的高8位),用于对字符值进行位屏蔽比较。例如,如果你的协议中某个控制字符的奇偶校验位可能是任意值(不参与匹配),你可以将RCCM对应位设为0来屏蔽它。这增加了匹配的灵活性。一个重要的实操细节:如果不需要屏蔽功能,RCCM应设置为0xE0FF(即高8位为1110 0000),这确保了所有8位都参与比较,避免因未定义而产生不可预知的行为。
2.2 同步与透明模式:协议的两种“语法”
BISYNC协议有正常模式和透明模式两种“语法”。硬件需要知道当前使用的是哪一种。
- 正常模式:控制字符(如SOH, STX, ETX)具有特殊含义,一旦出现就触发相应操作(如开始帧、结束帧)。
- 透明模式:为了解决数据字段中可能出现与控制字符相同字节值的问题,引入了DLE(Data Link Escape,数据链路转义)字符。在透明模式下,只有当控制字符紧跟在DLE之后时,才被解释为控制字符。如果数据中恰好有一个字节等于DLE,则发送方会发送两个连续的DLE,接收方会将其还原为一个数据DLE。
MPC8560的SCC通过PSMR[RTR]位和BSYNC、BDLE寄存器来协同管理这两种模式。
PSMR[RTR]:接收透明模式使能位。置1后,接收器只会在收到一个有效的DLE字符后,才去检查下一个字符是否为控制字符。BSYNC寄存器:主要定义SYNC字符及其处理方式。BSYNC[V]有效时,在非搜索模式下收到的SYNC字符会被丢弃(不存入缓冲区)。BSYNC[DIS]用于在透明模式下禁用SYNC剥离。BDLE寄存器:定义DLE字符及其处理方式。其V和DIS位的功能与BSYNC类似,但针对DLE字符。在透明模式下,硬件会自动处理DLE-DLE(转义为一个数据DLE)和DLE-SYNC(作为空闲序列)序列。
配置心得:在透明模式下,必须同时正确设置PSMR[RTR]、BDLE和BSYNC寄存器。一个常见的错误是只开启了透明模式但未正确配置DLE处理,导致数据流解析混乱。务必根据协议规范,明确SYNC和DLE字符的具体值,并设置好是否剥离。
2.3 缓冲区描述符(BD):DMA的“任务工单”
这是连接硬件协议引擎与系统内存的桥梁。BD是一个位于Dual-Port RAM中的数据结构,由CPU准备,由CP(通信处理器)执行和更新。它告诉DMA引擎:数据从哪里来(TxBD)或到哪里去(RxBD),数据有多长,以及如何处理这块数据。
接收BD(RxBD)的关键状态位:
E(空):CPU将其置1,表示此缓冲区空闲,CP可以存入数据。CP在填满缓冲区或因错误关闭缓冲区后,将其清0。C(控制字符):CP在关闭缓冲区时,如果最后一个字节是匹配到的控制字符,则置位此位。这告诉CPU,帧是因正常结束符而终止的。B(BCS接收):CP在关闭缓冲区时,如果缓冲区中包含接收到的BCS字节,则置位此位。这对于校验至关重要。OV(过载)、CD(载波丢失)、PR(奇偶校验错误)、CR(BCS错误):这些错误标志位帮助CPU快速定位通信问题。
发送BD(TxBD)的关键控制位:
L(消息最后):指示当前缓冲区是否是整个消息块的最后���个缓冲区。只有最后一个缓冲区的L位需要置1。TB(发送BCS):仅在L=1时有效。置1表示在该缓冲区数据发送完毕后,硬件应自动计算并发送BCS序列。TD(发送DLE):置1时,硬件会在发送本缓冲区数据之前,自动插入一个DLE字符。这在透明模式下构建DLE+控制字符序列时非常方便,无需在数据缓冲区中预留位置。TR(透明模式):指示发送器在发送完此缓冲区后进入或保持在透明模式。B(BCS使能):决定此缓冲区内的数据是否参与发送端的BCS计算。通常,帧头(如SOH)不参与校验,其所在缓冲区的B位应设为0。
DMA工作流:CPU初始化一个BD链表(通过W“回绕”位标识最后一个BD)。例如,对于接收,CPU准备一系列E=1的RxBD。当SCC硬件收到数据并识别出帧结束(或缓冲区满,或出错),它会自动将数据通过DMA存入当前RxBD指向的内存,更新数据长度和状态位,将E清0,并触发中断(如果I位使能)。CPU在中断服务程序中,处理已满(E=0)的缓冲区,然后重新将E置1,将其放回链表,供CP再次使用。这个过程实现了“零拷贝”或“最少拷贝”的高效数据流转。
3. 实战配置与编程步骤详解
理解了核心机制后,我们来看一个完整的SCC2初始化为BISYNC模式的编程示例。这个过程就像给一个功能强大的机器设定工作流程,每一步都有其明确目的。
3.1 硬件引脚与时钟配置
任何通信外设的使用,第一步永远是管脚复用和时钟路由。MPC8560的SCC引脚与并行I/O口复用。
- 配置端口D:使能TXD2(发送)和RXD2(接收)。通常需要设置相应管脚为外设功能(设置
PPARD),并将TXD方向设为输出(PDIRD对应位置1),RXD方向设为输入(对应位置0)。同时,可能需要清除PSORD中对应位的特殊选项。 - 配置流控引脚:如果使用RTS/CTS硬件流控,需要配置RTS2(输出)、CTS2(输入)和CD2(载波检测,输入)对应的端口C和D引脚。步骤同上,设置功能与方向。
- 配置时钟引脚:假设使用外部时钟CLK3。需要配置端口C的CLK3引脚为外设输入功能。
- 内部多路复用:通过
CMXSCR寄存器,将SCC2的接收和发送时钟源(R2CS,T2CS)都选择为CLK3。同时,确保SCC2连接到NMSI(非复用串行接口),即其专用的引脚组。
注意:引脚配置是嵌入式开发中最容易出错的地方之一。务必查阅MPC8560的芯片手册中关于“Signal Description”和“Pin Assignment”的章节,确认你使用的具体引脚编号及其复用控制寄存器的确切位域。错误的配置会导致信号根本无法输出或输入。
3.2 SCC核心寄存器初始化序列
这是配置的核心,顺序很重要。
- 设置BD基址:在双端口RAM中规划好RxBD和TxBD表的位置。将RxBD表的起始地址写入
RBASE,TxBD表的起始地址写入TBASE。例如,RBASE = 0x0000,TBASE = 0x0008(假设每个BD占8字节)。 - 执行初始化命令:向CP的命令寄存器
CPCR写入命令0x04a1_0000(INIT RX AND TX PARAMETERS)。这个命令会触发CP内部根据RBASE和TBASE更新其当前的BD指针(RBPTR,TBPTR)。忘记这一步是常见错误,会导致DMA无法找到BD。 - 配置FIFO控制:设置
RFCR和TFCR寄存器,通常为0x10,表示正常操作,使用8位数据。 - 设置最大接收缓冲区长度:根据系统内存和性能考量,设置
MRBLR。它定义了单个RxBD所能接收的最大字节数。超过此长度,即使帧未结束,CP也会关闭当前缓冲区并产生RXB中断。需要根据协议最大帧长合理设置。 - 初始化BCS相关寄存器:
PRCRC(接收CRC预设值)和PTCRC(发送CRC预设值):对于CRC-16,通常初始化为0x0000或0xFFFF(取决于协议变种)。对于LRC(纵向冗余校验),偶校验初始化为0x00,奇校验为0xFF。- 清除
PAREC(奇偶校验错误计数器)以获得清晰的起始状态。
- 配置协议字符:
BSYNC:写入SYNC字符值。例如,0x8033表示V=1(有效),SYNC字符为0x33。DSR:写入同步序列。在BISYNC中,通常发送两个连续的SYNC字符作为帧间填充或同步头。GSMR_H[SYNL]定义从这个寄存器中取多少位作为同步模式。BDLE:写入DLE字符值。例如,0x8055表示V=1,DLE字符为0x55。
- 配置控制字符表:这是关键。根据你的协议定义,填充
CHARACTER1到CHARACTER8。例如,定义ETX:CHARACTER1 = 0x6077(ETX=0x77, B=1, H=1)。不用的条目可以设为0x8000(E=1,无效条目)。设置RCCM = 0xE0FF。 - 初始化BD数据结构:
- RxBD:在内存中创建RxBD实例并初始化。
Status and Control字段设为0xB000(E=1,I=1使能中断,W=0假设不是最后一个BD)。Data Length初始为0,Buffer Pointer指向一个预先分配好的内存缓冲区(如0x00001000)。 - TxBD:同样初始化。
Status and Control字段设为0xBD20(R=1准备发送,I=1,L=1最后一个缓冲区,TB=1发送BCS,B=1数据参与BCS计算)。Data Length设为要发送的字节数(如5),Buffer Pointer指向发送数据缓冲区。
- RxBD:在内存中创建RxBD实例并初始化。
- 事件与中断配置:
- 向
SCCE写入0xFFFF以清除所有可能挂起的事件标志。 - 配置
SCCM中断掩码寄存器,使能你需要的中断。例如,0x0013使能了TXE(发送错误)、TXB(发送缓冲区完成)和RXB(接收缓冲区完成)中断。 - 在系统级的CPM中断控制器中,使能SCC2对应的中断线。
- 向
- 配置协议模式与使能:
- 配置
GSMR_H和GSMR_L。GSMR_L用于选择协议模式(BISYNC)、设置诊断模式(如让CTS/CD自动控制收发)、配置时钟等。特别注意:初始配置时,先不要使能收发器(ENT和ENR位保持为0)。 - 配置
PSMR(协议特定模式寄存器)。这是BISYNC的核心控制。例如,0x0600表示:CRC=01(CRC-16),RBCS=1(使能接收BCS计算),RTR=0(正常接收模式,非透明)。
- 配置
- 最后使能收发器:这是关键一步。再次向
GSMR_L写入值,这次将ENT和ENR位置1,正式启动SCC的发送和接收功能。确保其他配置位不变。分两步操作可以避免在配置过程中产生意外的发送或接收行为。
3.3 数据收发流程与中断处理
初始化完成后,系统开始运行。
- 发送流程:CPU将待发送数据填入TxBD指向的缓冲区,设置好TxBD的控制位(特别是
R=1),然后SCC硬件会自动开始发送。发送完整个缓冲区(及可选的BCS)后,CP会将TxBD的R位清0,并置位SCCE[TXB](如果使能了中断)。CPU在中断服务程序中,检查发送状态(如是否有UN下溢或CTCTS丢失错误),然后可以准备下一个要发送的数据和BD。 - 接收流程:SCC硬件在接收到同步字符后开始接收数据,并存入当前
E=1的RxBD指向的缓冲区。当发生以下事件之一时,CP会关闭当前RxBD(清E位)并可能触发RXB中断:- 接收到一个在控制字符表中定义且
B=0的字符(如ENQ)。 - 接收到一个定义且
B=1的字符(如ETX),并随后完成了BCS字节的接收。 - 接收缓冲区已满(达到
MRBLR)。 - 发生接收错误(如过载OV、载波丢失CD、奇偶错误PR、BCS错误CR)。
- 软件发出了
CLOSE RX BD或ENTER HUNT MODE命令。 CPU在RXB中断服务程序中,遍历所有E=0的RxBD,读取Data Length和状态位(C,B,CR,OV等),从而知道收到了多少数据、帧是如何结束的、是否有错误。处理完数据后,CPU必须将该RxBD的E位置1,并可能重置Data Length,然后将其重新链接到BD链表中,以供CP下次使用。
- 接收到一个在控制字符表中定义且
4. 高级技巧与避坑指南
在实际项目中,仅仅让代码跑通是不够的,稳定和高效才是目标。以下是一些从实战中总结的经验和常见陷阱。
4.1 性能优化策略
- 缓冲区大小与数量权衡:
MRBLR和BD链的长度需要仔细权衡。缓冲区太小(如16字节),会导致频繁的RXB中断和BD切换开销,增加CPU负载。缓冲区太大,则会增加内存占用和数据处理延迟。一个折中的方案是设置MRBLR略大于最常见的帧长,并准备一个足够长的BD链(例如8-16个),使得在CPU处理一个已满缓冲区的时间内,CP总有空的缓冲区可用,避免BSY(忙,无缓冲区)错误。 - 利用连续模式(CM):在RxBD和TxBD中都有一个
CM(连续模式)位。当CM=1时,CP在服务完这个BD后不会自动清除E(Rx)或R(Tx)位。这意味着该BD会被反复使用。这在需要循环发送固定数据(如心跳包)或希望将接收数据始终存入同一块内存进行实时处理时非常有用。但需谨慎:在接收端,如果发生错误,即使CM=1,E位也会被清0,以防止错误数据被覆盖。 - 灵活使用控制字符识别:对于复杂的、包含多种帧类型的协议,可以利用“软件辅助+硬件加速”的混合模式。如手册30.16节所述,可以先使能每个字节接收中断(
SCCM[RCH]=1),让CPU分析帧的前几个字节(如SOH、STX、DLE),以确定帧类型和后续处理方式(例如,是进入透明模式还是重置BCS)。一旦确定,就屏蔽字节中断,让硬件依靠控制字符表自动接收完剩余帧,直到匹配到结束符(如ETX)再产生RXB中断。这平衡了灵活性与效率。
4.2 常见问题排查实录
数据根本收不到或发不出:
- 首要检查时钟和引脚:用示波器或逻辑分析仪测量TXD、RXD、CLK引脚是否有信号。没有时钟,一切免谈。确认引脚复用配置绝对正确,这是最高频的错误原因。
- 检查BD状态机:确认初始化的RxBD的
E位是否为1(空,等待接收),TxBD的R位是否为1(就绪,等待发送)。CP只会操作E=1或R=1的BD。 - 检查SCC使能:确认
GSMR_L中的ENT和ENR位是否已置1。配置顺序错误可能导致其未被正确使能。 - 检查流控:如果使用了CTS/RTS,确保CTS输入信号有效(为低电平),否则发送器会一直等待。
只能收到一部分数据,或帧被提前截断:
- 检查
MRBLR:接收到的数据长度是否刚好等于MRBLR?如果是,说明缓冲区太小,帧还没结束缓冲区就满了。增大MRBLR或使用多个缓冲区(通过BD链表)。 - 检查控制字符表:是否无意中定义了某个数据域中可能出现的字节值为控制字符?这会导致硬件误认为帧已结束。仔细检查协议数据编码,确保控制字符值是唯一的,或者使用透明模式来避免数据混淆。
- 检查
PSMR[RBCS]位:如果接收BCS未使能(RBCS=0),那么即使控制字符的B=1,硬件也不会去等待和接收BCS字节,可能会直接关闭缓冲区。
- 检查
CRC/LRC校验总是失败:
- 检查
PRCRC/PTCRC初始值:CRC-16有不同的变种(如CRC-16-CCITT, CRC-16-IBM),其初始值可能为0x0000或0xFFFF。LRC的初始值也分奇偶。必须与通信对端的协议实现严格一致。 - 检查哪些数据参与了计算:通过TxBD的
B位和PSMR[RBCS]位,可以控制哪些数据参与发送端计算和接收端校验。确保帧头、填充字符等不参与校验的部分,其对应的B=0或在接收端通过及时操作RBCS将其排除。 - 检查字节序和位序:
PSMR[RVD]位可以反转数据的位序(MSB first vs LSB first)。确保发送端和接收端的设置一致。 - 在透明模式下:注意硬件会自动剥离前导的DLE字符,并且不将其计入BCS。计算软件校验时,必须模拟完全相同的行为。
- 检查
中断无法触发:
- 三层中断使能检查:这是一个经典的嵌入式问题。第一层:BD本身的
I位是否置1?第二层:SCC级的中断掩码SCCM对应位是否置1?第三层:系统级的CPM中断控制器(SIMR_L)中,该SCC对应的中断线是否被使能?缺一不可。 - 检查
SCCE标志:即使中断未使能,事件标志SCCE也会被置位。在调试时,可以轮询SCCE寄存器,查看TXB、RXB等位是否变化,以判断硬件是否正常工作。 - 中断服务程序(ISR)中必须清除标志:在SCC的ISR中,必须通过向
SCCE的相应位写1来清除事件标志。否则,中断会持续触发。
- 三层中断使能检查:这是一个经典的嵌入式问题。第一层:BD本身的
4.3 透明模式下的特殊处理
透明模式是BISYNC的难点,但MPC8560的硬件支持使其变得可控。
- 发送透明数据:如果要发送的数据中包含DLE字符(0x10),你需要发送两个连续的0x10。硬件在
TR=1(透明模式)时,会自动完成这个“字节填充”过程。你只需要在数据缓冲区中放入一个0x10,硬件发送时会自动将其变为两个。对于控制字符(如ETX),在透明模式下你需要发送DLE + ETX。你可以通过设置TxBD的TD=1,让硬件在发送缓冲区数据前自动插入一个DLE,这样你只需在缓冲区中放入ETX即可。 - 接收透明数据:接收端设置
PSMR[RTR]=1和BDLE[V]=1。硬件在收到一个DLE后,会检查下一个字符:- 如果是另一个DLE,则将其作为一个数据字节存入缓冲区。
- 如果是SYNC,则将其作为同步序列丢弃(如果配置为丢弃)。
- 如果是控制字符表中的字符(如ETX),则按控制字符处理(结束帧等)。
- 如果都不是,则报告
DLE follow character error(RxBD的DL位置1)。
- BCS计算:在透明模式下,硬件会自动排除用于转义的DLE字符(即每个
DLE-DLE序列中的第一个DLE)以及DLE-SYNC序列中的两个字符,使其不参与BCS计算。这完全由硬件处理,大大减轻了软件负担。
掌握MPC8560 SCC的BISYNC模式,意味着你能够为嵌入式系统赋予高效、可靠处理传统同步协议的能力。其精髓在于通过精细的寄存器配置,将协议规则“告知”硬件,然后依靠硬件与DMA的协同,实现数据流的高吞吐量、低CPU占用的自动化处理。从理解控制字符表这张“硬件词典”,到驾驭缓冲区描述符这套“DMA工单”,再到妥善处理透明模式和各类异常,每一步都需要对协议和硬件机制的深刻理解。调试过程往往离不开示波器、逻辑分析仪和对状态寄存器的耐心观察。当你的系统能够稳定地处理成千上万的BISYNC帧而CPU负载依然轻松时,你会觉得这些前期的深入研究和细致配置都是值得的。这种将经典协议与现代硬件加速相结合的设计思路,在许多需要兼容旧系统或特定行业标准的嵌入式产品中,依然具有强大的生命力。