Major

V1

2023/01/15阅读:16主题:萌绿

YTM32芯片内部ECC处理机制

作为国产车规芯片的新势力,YTM32芯片全系列都配备Meomory ECC机制,可以有效的增强芯片运行稳定性,避免因为内存位翻转导致芯片产生严重故障,本片文章我们针对内存ECC的基本机制,实现原理和使用时的注意事项等几个方面来介绍一下YTM32系列芯片的ECC处理机制。

ECC的基本概念

ECC全称Error Checking and Correcting, 属于一种错误检查和纠正算法,典型的ECC算法一般可以做到纠正单比特错误和检查2比特错误。

在介绍ECC算法之前我们先来看一种简单的校验算法:奇偶校验。所谓的奇偶校验实际上就是在数据传输的末尾增加1比特的校验信息,从而保证完整的数据帧一定是奇数或者偶数,假如采用偶数校验的方式,发送方对偶数数据补充比特0,对于奇数数据补充比特1,这样发送的数据一定是偶数,接收方收到数据之后就对完整的数据帧进行判断, 如果不是偶数则代表数据出错。

上述这种奇偶校验算法通过增加1比特的额外数据,接收方就可以根据额外是数据判断数据是否正确,从而实现对数据的校验,但是针对奇偶校验的方式,如果有2个比特数据发生反转,那么接受方依然会认为接收到的数据是正常数据,如果有1个比特数据异常,接收方只能判断数据是异常的,并不能从接收到的数据恢复出正确的数据(因为无法判断具体是哪一位出现了异常),从上面两种情况来看,奇偶校验实际上是一种只能检验单比特数据错误的校验算法。

相对于奇偶校验算法,ECC校验算法通过增加更多的额外数据来实现对传输数据的错误检查和错误纠正。因为实际芯片中,存储单元(包含芯片内部SRAM和Flash)通常发生的是位的翻转,也就是单比特错误居多,针对这种错误,ECC一般是实现1比特的错误纠正和2比特错误的检查,嵌入式芯片的ECC组合一般是32+7和64+8的组合方式。

ECC结构
ECC结构

从上述组合来看,当有效数据位数增加时候,额外的ECC数据并没有显著增加,但是因为MCU中数据的存储还是突发性读写多一些,所以也不能无限的增加有效数据的长度,根据处理器特性和SRAM以及Flash的基本特性,在MCU中我们对于SRAM一般采样32+7的ECC校验方式,而Flash则是采用64+8的校验方式。

ECC RAM的访问方式

对于MCU内部SRAM,支持ECC的读写时候需要在写入SRAM数据的的时候计算好数据对应的ECC并一起写入,而读取操作的时候需要同时读取数据和ECC校验信息,读取之后根据ECC对数据进行校验,校验结束之后将数据返回系统中使用。

SRAM ECC 框图
SRAM ECC 框图

从上图来看,对于SRAM的读写都是32位的形式操作的,但是我们知道C语言中有很多基于字节或者半字的操作方式,对于这种形式,我们并不能直接通过SRAM的byte enable接口实现byte的操作。因为ECC是基于32位的,着32位中任意bit的更改都需要重新进行ECC的运算,而重新计算ECC需要知道修改后的整个32位数据,所以在对有ECC的SRAM进行byte或者half word操作的时候,SRAM控制器首先会读出SRAM中原有的数据,将这个数据修改之后,重新计算ECC,然后将结果和新的数据整体写入到SRAM中。而对于32位的写入则可以直接进行ECC计算,然后将数据和ECC直接写入。

ECC RAM的初始化

我们知道嵌入式处理器的SRAM在上电之后内容是随机的,这种情况下,如果读取SRAM的内容并进行ECC校验,那么很大概率上是会出现ECC错误的。所以我们在使用支持ECC的SRAM之前都需要手动对SRAM进行初始化操作,这个操作就是简单的向SRAM中按照32位的宽度写入一个任意值就可以了。注意初始化的时候必须要按照32位的形式写入,因为按照字节或者半字的方式写入的时候,系统会先读后写,那么读取的过程中就会出现ECC错误。

ECC的初始化一般放在MCU的启动汇编代码中,因为没有初始化ECC的时候,堆栈甚至都不能使用,YTM32芯片在GCC环境的ECC初始化通过如下代码实现:

#ifndef START_NO_ECC_INIT

    /* Init ECC RAM */

    ldr r1, =__RAM_START
    ldr r2, =__RAM_END

    subs    r2, r1
    subs    r2, #1
    ble .LC5

    movs    r0, 0
    movs    r3, #4
.LC4:
    str r0, [r1]
    add	r1, r1, r3
    subs r2, 4
    bge .LC4
.LC5:
#endif

上述代码中,可以通过定义START_NO_ECC_INIT 实现初始化时绕过ECC初始化,旧版本SDK通过定义START_FROM_FLASH的宏开启ECC初始化功能,ECC的初始化范围是从__RAM_START__RAM_END,这两个地址是在link文件中定义的,用户可以根据应用需求修改相应的地址范围,注意这里初始化ECC的memory越大,系统启动的时间越长。

ECC未正常初始化可能导致的异常

YTM32芯片在SRAM产生ECC错误的时候会产生Bus Error或者hard fault,用户在使用过程中如果发现芯片在调试过程中使用正常,但是在芯片重新上电之后就会出现异常,那么可以检查一下是否SRAM ECC没有正常初始化,比如上述过程中的START_FROM_FLASH宏定义是否在汇编调试阶段有定义(针对旧版本SDK)。

还有一种方式就是通过调试器查看系统的SRAM,如果发现有的SRAM可以读,但是有的SRAM地址无法正确读,那么就是ECC没有正常初始化。

SRAM ECC错误注入

在程序开发过程中,考虑到功能安全的需求,我们还需要考虑出现ECC错误情况的处理,实际上SRAM上比特位翻转式一个小概率事件,测试过程很难出现。考虑到这种情况,YTM32 MCU增加了一个EMU的模块,专门用于ECC错误的捕获和错误注入。

EMU模块的基本框图如下:

SRAM EMU模块框图
SRAM EMU模块框图

EMU实际上是在SRAM的Read path上增加的一个模块,EMU可以在SRAM的读取结果上和EMU设置的一个mask进行异或运算,从而实现读取数据的位翻转,所以EMU可以实现任意地址上任意bit的位翻转,通过这种形式,我们就可以模拟SRAM出现ECC错误。

另外EMU还会监测ECC decode的结果,当系统产生ECC错误的时候,EMU会捕获这个异常并记录出现ECC错误的地址和异常类型(单比特错误还是多比特错误),应用中通过读取EMU的错误信息可以决定如何处理ECC错误。

对于ECC错误的处理方式,可以分为如下几种情况:

  1. 如果系统允许复位的话,可以直接记录诊断信息后复位运行,这样SRAM整体都会重新初始化成正常内容
  2. 针对单比特错误,因为ECC可以直接纠正结果,可以直接读取产生ECC错误地址上的内容,然后将内容重新写会到该地址即可恢复正常。注意如果ECC错误是通过EMU模拟实现的,则需要关闭EMU注入通道,否则再次读取的时候依然会有ECC错误,另外因为ECC是纠1检2的算法,如果出现多于2比特的错误,这种情况SRAM的读取结果可能会有正常,单比特错误和多比特错误几种结果。
  3. 针对多比特错误,因为无法恢复正确信息,应用只能向错误地址写入一个默认值,或者通过复位操作恢复正常值。

Flash ECC校验

Flash内部也是通过电荷状态来存储信息的,虽然电荷的状态大部分时间都是稳定的,但是当受到某些干扰之后,电荷状态也有可能发生反转。所以Flash的ECC校验对于车规芯片也是一个基础要求,Flash因为不支持随机的写入,所以ECC的操作方面比较简单。

首先,Flash默认擦除状态是全1的,而配套的ECC算法可以保证全1的ECC校验值也是全1,也就是Flash擦除状态下,对Flash的读操作并不会产生ECC错误,而Flash的写入都是通过一系列的命令实现的,在写入的时候会同时计算好ECC,并将数据和ECC校验值一起写入到Flash的Array中,写入完成之后,数据依然可以正确读取,所以Flash ECC对用户而言大部分情况是完全透明的。这种情况,即使Flash出现单比特的错误,数据可以正常纠正,也可以完全保证数据的完整性。

对于功能安全要求比较高的程序,应用程序还需要针对Flash的ECC进行处理,和SRAM ECC错误处理的方式类似,Flash ECC错误处理可以分为如下几种形式:

  1. 针对单比特错误,因为可以正确恢复原始数据,应用程序需要先记录相应的诊断数据,然后先备份Flash出错数据所在的扇区,然后将扇区擦除,然后从备份地址将原有数据重新写入到擦除后到扇区。
  2. 如果出现的是多比特的数据,如果错误出现在程序区域,那么只能记录诊断数据,然后尝试运行备份APP程序,尝试系统复位,或者重新下载程序
  3. 如果多比特错误出现在数据区域,那么应用程序需要尝试使用默认值替代错误区域。

总之,Flash的ECC错误处理必须将出现错误的扇区进行擦除和重新编程才能正确的清除掉ECC错误,当然同一个地址产生多位的翻转概率还是非常低的。

分类:

后端

标签:

后端

作者介绍

Major
V1