这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 活动中心 » 板卡试用 » 【MAX78000FEATHER】ECC功能验证使用

共1条 1/1 1 跳转至

【MAX78000FEATHER】ECC功能验证使用

高工
2025-10-05 13:03:52     打赏

【简介】

MAX78000 的SRAM 是支持ECC特性,我们通过关闭ECC在开启ECC触发ECC 异常来验证ECC 功能。

image.png

我们通过如下代码来验证SRAM ECC功能

/******************************************************************************
 *
 * Copyright (C) 2022-2023 Maxim Integrated Products, Inc. (now owned by 
 * Analog Devices, Inc.),
 * Copyright (C) 2023-2024 Analog Devices, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 ******************************************************************************/

/**
 * @file    main.c
 * @brief   Demonstration of SRAM Error Correcting Code (ECC) features
 * @details This program demonstrates single and double-bit error detection and
 *          single-bit correction for SRAM memories.
 */

/***** Includes *****/
#include <stdio.h>
#include <stdint.h>
#include "mxc_device.h"
#include "led.h"
#include "board.h"
#include "gcr_regs.h"
#include "mcr_regs.h"

/***** Definitions *****/
#define STRINGIFY(x) #x
#define TOSTRING(x) STRINGIFY(x)

/***** Globals *****/
volatile uint32_t badData;
volatile uint32_t eccFlag;
volatile uint32_t eccErr;
volatile uint32_t eccDErr;
volatile uint32_t eccAddr;

// Find the highest address in RAM, subtract the portion taken away by ECC
uint32_t ramTop = (MXC_SRAM_MEM_BASE + (MXC_SRAM_MEM_SIZE * 0.8));

/***** Functions *****/

void ECC_IRQHandler(void)
{
    eccErr = MXC_GCR->eccerr;
    eccDErr = MXC_GCR->eccced;
    eccAddr = MXC_GCR->eccaddr;
    eccFlag = 1;

    MXC_GCR->eccerr = eccErr;
    MXC_GCR->eccced = eccDErr;
}

// *****************************************************************************
int main(void)
{
    unsigned int i, test_fail, test_pass;
    volatile uint32_t *cursor;

    test_fail = test_pass = 0;

    printf("\n\n***** " TOSTRING(TARGET) " SRAM ECC Example *****\n\n");
    printf("This example will corrupt a word of data\n");
    printf("and ensure that the ECC interrupts on an error\n");
    printf("when the corrupted address is read\n\n");

    // Clear all ECC Errors -- write-1-to-clear (cast is necessary to avoid compiler warning about assigning value to itself)
    MXC_GCR->eccerr = (volatile uint32_t)MXC_GCR->eccerr;
    MXC_GCR->eccced = (volatile uint32_t)MXC_GCR->eccced;

    // Enable interrupts for ECC errors
    MXC_GCR->eccie |= MXC_F_GCR_ECCIE_RAM;
    NVIC_EnableIRQ(ECC_IRQn);

    // Scan all of memory, which should not cause any errors to be detected
    printf("Preliminary scan to ensure no pre-existing ECC errors\n");
    eccFlag = 0;

    for (i = MXC_SRAM_MEM_BASE; i < ramTop - sizeof(uint32_t); i += sizeof(uint32_t)) {
        cursor = (uint32_t *)i;
        (volatile uint32_t) * cursor; // Force a read of the memory location.

        if (eccFlag) {
            break;
        }
    }

    printf("%d\n", ramTop);

    if (eccFlag) {
        printf("ECC Error:              0x%08x\n", eccErr);
        printf("ECC Not Double Error:   0x%08x\n", eccDErr);
        printf("ECC Error Address:      0x%08x\n", eccAddr);
        printf("FAIL: Error found in preliminary memory scan\n");
        test_fail++;
    } else {
        printf("PASS: No errors\n");
        test_pass++;
    }

    // Initialize data
    badData = 0xDEADBEEF;

    printf("\nData before Corruption: 0x%08x\n", badData);
    printf("Address of data: 0x%08x\n", &badData);

    // Disable ECC so data can be corrupted
    MXC_MCR->eccen &= ~MXC_F_MCR_ECCEN_RAM0;
    badData = 0xDEADBEEE;
    MXC_MCR->eccen |= MXC_F_MCR_ECCEN_RAM0;

    printf("\nData after single-bit error: 0x%08x\n", badData);
    printf("ECC Error:              0x%08x\n", eccErr);
    printf("ECC Not Double Error:   0x%08x\n", eccDErr);
    printf("ECC Error Address:      0x%08x\n", eccAddr);

    if (eccFlag) {
        printf("PASS: An ECC Error was found\n");
        eccFlag = 0;
        test_pass++;
    } else {
        printf("FAIL: Error not detected!\n");
        eccFlag = 0;
        test_fail++;
    }

    // Disable ECC so data can be corrupted
    MXC_MCR->eccen &= ~MXC_F_MCR_ECCEN_RAM0;
    badData = 0xDEADBEEC;
    MXC_MCR->eccen |= MXC_F_MCR_ECCEN_RAM0;

    printf("\nData after double-bit error: 0x%08x\n", badData);
    printf("ECC Error:              0x%08x\n", eccErr);
    printf("ECC Not Double Error:   0x%08x\n", eccDErr);
    printf("ECC Error Address:      0x%08x\n", eccAddr);

    if (eccFlag) {
        printf("PASS: An ECC Error was found\n");
        eccFlag = 0;
        test_pass++;
    } else {
        printf("FAIL: Error not detected!\n");
        eccFlag = 0;
        test_fail++;
    }

    printf("\n# Passed: %u, # Failed: %u, Test %s\n", test_pass, test_fail,
           test_fail ? "FAIL!" : "Ok");
    printf("Example Complete\n");

    // Return the ECC back to its POR state (disabled)
    MXC_MCR->eccen &= ~MXC_F_MCR_ECCEN_RAM0;

    if (test_fail != 0) {
        printf("\nExample Failed\n");
        return E_FAIL;
    }

    printf("\nExample Succeeded\n");
    return E_NO_ERROR;
}

上述代码运行后按照预期的触发了ECC错误并打印了对应的错误地址信息

image.png


共1条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]