【简介】
MAX78000 的SRAM 是支持ECC特性,我们通过关闭ECC在开启ECC触发ECC 异常来验证ECC 功能。
我们通过如下代码来验证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错误并打印了对应的错误地址信息