SRAM完整性验证——读写整个外部SRAM验证是否损坏

SRAM完整性验证——读写整个外部SRAM验证是否损坏


前言

本文记录了GD32进阶学习中小作业的解决办法,本次遇到的问题是如何读写整个外部sram,并输出信息实现对外部sram的完整性验证。


一、什么是SRAM

SRAM是静态随机存取存储器的缩写,可读可写,掉电失数据。

一般常用于cpu的一二级缓存当中,速度快,价格贵,GD32F303ZET6内部SRAM容量为96kb,本次使用的开发板上还集成有IS62WV51216外部SRAM芯片。

本次实验外部SRAM地址范围为0x6c000000--0x6c0fffff。

二、外部SRAM驱动方法

1.使用EXMC驱动

EXMC选中Bank0中的Region3区域进行控制 

/*********************************************************************************************************
* 函数名称:ConfigBank0Region3
* 函数功能:配置外部存储Bank0的Region3
* 输入参数:void
* 输出参数:void
* 返 回 值:void
* 创建日期:2021年07月01日
* 注    意:外部SRAM位于外部存储Bank0的Region3
*********************************************************************************************************/
static void ConfigBank0Region3(void)
{
  exmc_norsram_parameter_struct        sram_init_struct;
  exmc_norsram_timing_parameter_struct sram_timing_init_struct;

  //使能EXMC时钟
  rcu_periph_clock_enable(RCU_EXMC);

  //外部SRAM读写时序
  sram_timing_init_struct.asyn_access_mode = EXMC_ACCESS_MODE_A; //模式A,异步访问SRAM
  sram_timing_init_struct.asyn_address_setuptime = 0; //异步访问地址建立时间
  sram_timing_init_struct.asyn_address_holdtime  = 0; //异步访问地址保持时间
  sram_timing_init_struct.asyn_data_setuptime    = 3; //异步访问数据建立时间
  sram_timing_init_struct.bus_latency            = 0; //同步/异步访问总线延时时间
  sram_timing_init_struct.syn_clk_division       = 0; //同步访问时钟分频系数(从HCLK中分频)
  sram_timing_init_struct.syn_data_latency       = 0; //同步访问中获得第1个数据所需要的等待延迟

  //Region3配置
  sram_init_struct.norsram_region    = EXMC_BANK0_NORSRAM_REGION3; //Region3
  sram_init_struct.address_data_mux  = DISABLE;                    //禁用地址、数据总线多路复用
  sram_init_struct.memory_type       = EXMC_MEMORY_TYPE_SRAM;      //储存器类型为SRAM
  sram_init_struct.databus_width     = EXMC_NOR_DATABUS_WIDTH_16B; //数据宽度16位
  sram_init_struct.burst_mode        = DISABLE;                    //禁用突发访问
  sram_init_struct.nwait_config      = EXMC_NWAIT_CONFIG_BEFORE;   //等待输入配置
  sram_init_struct.nwait_polarity    = EXMC_NWAIT_POLARITY_LOW;    //等待输入信号低电平有效
  sram_init_struct.wrap_burst_mode   = DISABLE;                    //禁用包突发访问
  sram_init_struct.asyn_wait         = DISABLE;                    //禁用异步等待
  sram_init_struct.extended_mode     = DISABLE;                    //禁用扩展模式
  sram_init_struct.memory_write      = ENABLE;                     //使能写入外部存储器
  sram_init_struct.nwait_signal      = DISABLE;                    //禁用等待输入信号
  sram_init_struct.write_mode        = EXMC_ASYN_WRITE;            //写入模式为异步写入
  sram_init_struct.read_write_timing = &sram_timing_init_struct;   //读时序配置
  sram_init_struct.write_timing      = &sram_timing_init_struct;   //写时序配置
  
  //初始化Region3
  exmc_norsram_init(&sram_init_struct);
  
  //使能Region3
  exmc_norsram_enable(EXMC_BANK0_NORSRAM_REGION3);
}

2.主要内部函数

static u8   ReadByte(u32 addr);             //读取特定地址数据(1字节)
static void WriteByte(u32 addr, u8 data);   //往特定地址内写入1字节数据

/*********************************************************************************************************
* 函数名称:ReadByte
* 函数功能:读取特定地址数据(1字节)
* 输入参数:addr:读取地址
* 输出参数:void
* 返 回 值:读到的数据
* 创建日期:2021年07月01日
* 注    意:
*********************************************************************************************************/
static u8 ReadByte(u32 addr)
{
  return *(u8*)addr;
}

/*********************************************************************************************************
* 函数名称:WriteByte
* 函数功能:往特定地址内写入1字节数据
* 输入参数:addr:写入地址,data:写入数据(字节)
* 输出参数:void
* 返 回 值:void
* 创建日期:2021年07月01日
* 注    意:
*********************************************************************************************************/
static void WriteByte(u32 addr, u8 data)
{
  *(u8*)addr = data;
}

3.全填充测试函数

使用一个全填充函数对所有的SRAM区域进行读写测试,主要定义一个输出信息结构体,以及全填充测试函数test_sram_full

// 测试结果结构体
typedef struct {
    u32 first_fail_addr;//首次错误地址。
    u8 expected;//存储测试时预期写入的数据值(例如 0xFF或 0x00)。
    u8 actual;//记录从 first_fail_addr地址实际读取的数据值。
    u32 total_errors;//统计整个 SRAM 测试中发生错误的总次数。
} SRAM_TestResult;
/*********************************************************************************************************
* 函数名称:test_sram_full
* 函数功能:全填充测试函数
* 输入参数:void
* 输出参数:void
* 返 回 值:void
* 创建日期:2021年07月01日
* 注    意:
*********************************************************************************************************/
SRAM_TestResult test_sram_full(u8 pattern) 
{
    u8 value;
    u32 addr;
    SRAM_TestResult result = {0};
    for (addr = SRAM_START; addr <= SRAM_END; addr++)
    {
        WriteByte(addr, pattern); // 写入模式值
        value = ReadByte(addr); // 读取1字节
        if (value != pattern) 
        {
            if (result.total_errors == 0)
              { // 记录首个错误
                result.first_fail_addr = addr;
                result.expected = pattern;
                result.actual = value;
              }
            result.total_errors++;
        }
    }
    return result;
}

 三、调用函数输出


SRAM_TestResult test1;
SRAM_TestResult test2;

int main(void)
{
    // 测试1:全写0xFF
    test1 = test_sram_full(0xFF);
    printf("Test 1 (0xFF): Errors=%d, First Fail: 0x%X (Exp:0x%X, Act:0x%X)\n", 
           test1.total_errors, test1.first_fail_addr, test1.expected, test1.actual);
    // 测试2:全写0x00
    test2 = test_sram_full(0x00);
    printf("Test 2 (0x00): Errors=%d, First Fail: 0x%X (Exp:0x%X, Act:0x%X)\n", 
           test2.total_errors, test2.first_fail_addr, test2.expected, test2.actual);
}

总结

通过设置结构体动态错误记录,实现​记录首个错误地址及值,并统计错误总数,避免海量输出淹没关键信息。

同时查阅资料可知传统全写相同值可能掩盖以下问题:

  • ​地址线故障​​:高位地址线断路导致地址重叠(如0x6c0000000x6c000001因A0线故障被映射到同一单元)。

  • ​数据线粘连​​:某数据位始终为高/低电平(如D3粘连导致无法写入0)。

  • ​控制信号异常​​:片选(CS)或写使能(WE)信号失效。

可以通过地址线测试(Walking Bit)完善

SRAM_TestResult test_sram_addressing() {
    SRAM_TestResult result = {0};
    for (u32 addr = SRAM_START; addr <= SRAM_END; addr++) {
        u8 pattern = addr & 0xFF; // 地址低8位作为特征值
        WriteByte(addr, pattern);
        u8 value = ReadByte(addr);
        if (value != pattern) {
            if (result.total_errors == 0) {
                result.first_fail_addr = addr;
                result.expected = pattern;
                result.actual = value;
            }
            result.total_errors++;
        }
    }
    return result;
}

使用​​行走位模式​​(Walking Bit)写入地址特征值(如addr & 0xFF),使每个地址写入值唯一,解决传统全写相同值不能发现的:高位地址线断路导致地址重叠(如0x6c0000000x6c000001因A0线故障被映射到同一单元)的问题

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值