4、测试平台搭建:基于Zynq的故障注入平台、JTAG调试接口、UART通信协议

好,咱们进入第四章。这一章我打算聊聊测试平台的搭建。

说实话,做功能安全芯片测试,平台搭得好不好,直接决定了你后面几个月的日子好不好过。我自己就吃过这个亏——第一次做故障注入时,平台没搭稳,结果跑出来的数据全是乱的,排查了整整两周才发现是JTAG链路上有个虚焊。嗯,从那以后,我对平台搭建这件事就特别较真。

4.1 基于Zynq的故障注入平台

为什么选Zynq?说白了,它把ARM处理器和FPGA集成在了一个芯片里。这对我们做故障注入来说,简直是天作之合。

你想想看,ARM那边跑Linux,负责控制逻辑、通信、数据处理。FPGA这边呢,负责高速的故障注入操作。两边各干各的,互不干扰,效率还高。

我个人习惯把Zynq平台分成三个层次:

  • 控制层:ARM Cortex-A9,跑Linux,负责指令下发和结果回收
  • 执行层:FPGA逻辑,负责精确的故障注入时序控制
  • 被测层:目标芯片,通过JTAG或自定义接口连接

我在项目中遇到过一个问题:FPGA和ARM之间的数据交互,如果只用简单的GPIO来搞,速度根本跟不上。后来我改用AXI总线+DMA的方式,吞吐量直接提升了两个数量级。这个坑,我替你们踩过了。

核心要点:Zynq平台的优势在于软硬件协同。ARM做决策,FPGA做执行,两者通过AXI总线高速通信。这是目前工业界最主流的故障注入平台方案。

下面这张图是我自己整理的平台架构,你们可以参考一下:

ARM Cortex-A9 控制层 Linux系统 指令下发 / 结果回收 AXI总线 FPGA逻辑 执行层 故障注入时序控制 精确到纳秒级 JTAG/自定义 目标 芯片 被测层 UART通信模块 PC <-> Zynq 数据交互 上位机(PC) 数据分析 / 可视化 基于Zynq的故障注入平台架构 ARM + FPGA 协同工作,通过AXI总线高速通信 UART负责与上位机交互,JTAG负责与目标芯片通信

4.2 JTAG调试接口

JTAG这个接口,做芯片的人都不陌生。但在故障注入这个场景下,它的用法跟普通调试不太一样。

普通调试时,JTAG是用来读写寄存器、下载程序的。但在故障注入时,我们要用它来篡改数据——在芯片运行的某个精确时刻,通过JTAG把某个寄存器的值改掉,模拟一个硬件故障。

这里有个关键点:JTAG的时钟频率。我见过有人把JTAG时钟设到50MHz,结果故障注入的时序完全对不上。为什么?因为JTAG链路上的延时被忽略了。

我的经验:JTAG时钟建议设置在10-20MHz之间。太低影响效率,太高容易出时序问题。我曾经在25MHz下跑了一整天,数据看起来都正常,但后来发现每1000次注入就有1次时序偏差。这种概率性的问题最难排查。

JTAG接口的典型连接方式:

  • TMS:模式选择,控制JTAG状态机
  • TCK:时钟信号,所有操作同步于此
  • TDI:数据输入,我们要注入的故障数据从这里进去
  • TDO:数据输出,芯片的响应从这里读出来

还有一个容易被忽略的引脚——TRST(测试复位)。有些芯片没有这个引脚,但如果有,我建议一定要接上。为什么?因为有时候JTAG状态机跑飞了,TRST一下就能复位,省得你重新上电。

警告:JTAG链路上不要随意加长线缆。每增加10cm的线长,信号完整性就会下降一个档次。如果实在需要延长,请使用带屏蔽的差分线缆,并在接收端加终端匹配电阻。

4.3 UART通信协议

UART这个东西,看起来简单,但用好了能省不少事。

在Zynq平台上,UART主要承担两个角色:

  1. 控制通道:上位机通过UART向Zynq发送故障注入指令
  2. 数据通道:Zynq把故障注入结果通过UART回传给上位机

我个人习惯用115200波特率,8位数据位,1位停止位,无校验。这个配置兼容性最好,几乎所有的串口工具都支持。

但要注意一点:UART是异步通信,没有时钟线。这就意味着收发双方必须约定好波特率。如果两边对不上,收到的数据全是乱码。我刚开始做的时候,就因为这个原因浪费了半天时间——Zynq那边配的是115200,但上位机串口工具默认是9600。

下面是我常用的通信协议帧格式:

帧头 命令字 数据长度 数据域 校验和 帧尾
0xAA 0x55 1字节 1字节 N字节 1字节 0x0D 0x0A
固定值 操作类型 数据域长度 具体数据 累加和 回车换行

这个协议看起来简单,但够用了。我见过有人把UART协议搞得很复杂,又是CRC32又是加密的。说实话,在实验室环境下,没必要。简单可靠才是王道。

命令字我一般这样定义:

  • 0x01:单次故障注入
  • 0x02:连续故障注入(指定次数)
  • 0x03:读取芯片状态
  • 0x04:复位目标芯片
  • 0xFF:心跳包(用于检测链路是否正常)

避坑指南:我曾经遇到过一个问题——UART数据偶尔会丢包。排查了很久,最后发现是Zynq的UART FIFO深度设置太小了。数据来得快的时候,FIFO满了,后面的数据就直接丢了。解决方案是把FIFO深度调到最大,同时在软件层加一个超时重传机制。

最后说一句:UART的收发最好用中断方式,别用轮询。轮询会占用CPU,影响故障注入的实时性。我在Zynq上用的是PL端(FPGA)的UART IP核,配合中断控制器,基本能做到零丢包。

嗯,这一章的内容就这些。平台搭好了,后面的事情就顺了。

公众号:蓝海资料掘金营,微信deep3321