主题中讨论的其他器件:C2000WARE
您好、专家、
使用以下代码执行测试时、如果启用闪存 ECC、测试将进入 NMI ISR、
但是、如果如下代码所示禁用闪存 ECC 并再次编译代码、我们会发现测试仍将转到 NMI ISR、这毫无意义、
您能帮助解释原因吗? 谢谢。

C:\ti\c2000Ware_4_01_00_00\libraries\diagnostic\f28004x\examples\sdl_ex_flash_ecc_test
This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
您好、专家、
使用以下代码执行测试时、如果启用闪存 ECC、测试将进入 NMI ISR、
但是、如果如下代码所示禁用闪存 ECC 并再次编译代码、我们会发现测试仍将转到 NMI ISR、这毫无意义、
您能帮助解释原因吗? 谢谢。

C:\ti\c2000Ware_4_01_00_00\libraries\diagnostic\f28004x\examples\sdl_ex_flash_ecc_test
Vamsi、
很抱歉、此问题的回复较晚。
请检查稍后代码中的另一个点是否启用了 ECC。
-->不,代码是示例代码,只需修改以下代码,您就可以轻松重现此问题。
C:\ti\c2000Ware_4_01_00_00\libraries\diagnostic\f28004x\examples\sdl_ex_flash_ecc_test

2.您是否已经检查 NMI 寄存器以了解 NMI 源并确认它是闪存不舒适的错误?
是、请参阅以下寄存器:

//############################################################################# // // FILE: sdl_ex_flash_ecc_test.c // // TITLE: Test of ECC logic in Flash // //! \defgroup sdl_ex_flash_ecc_test Test of ECC logic in Flash //! <h1>sdl_ex_flash_ecc_test</h1> //! //! This example demonstrates how to test the Flash ECC logic functionality. //! //! A software test of the Flash ECC logic can be performed with the help of //! ECC test registers. Using the test registers, you can generate both single //! bit errors and uncorrectable errors. For additional details on the //! implementation of this diagnostic, see the "SECDED Logic Correctness Check" //! section in the device technical reference manual. //! //! \b External \b Connections \n //! - None. //! //! \b Watch \b Variables \n //! - \b nmiISRFlag - Indicates that the NMI was triggered and called the ISR. //! - \b nmiStatus - NMI status flags read in the ISR. //! - \b errorISRFlag - Indicates that the correctable ECC error interrupt was //! triggered and called the ISR. //! - \b errorStatus - Error status flags read in the ISR, indicating whether //! an error was single-bit or uncorrectable. //! - \b errorCount - Number of correctable errors detected read in the ISR. //! - \b errorType - For a single-bit error, indicates whether it was in the //! data or ECC bits. //! - \b dataOut - For a single-bit error, displays the corrected data. //! - \b result - Status of a successful detection and handling of ECC errors. //! // //############################################################################# // $TI Release: C2000 Diagnostic Library v3.00.00 $ // $Release Date: Thu Mar 3 16:52:56 IST 2022 $ // $Copyright: // Copyright (C) 2022 Texas Instruments Incorporated - http://www.ti.com/ // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: // // Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // // Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the // distribution. // // Neither the name of Texas Instruments Incorporated nor the names of // its contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // $ //############################################################################# // // Included Files // #include "driverlib.h" #include "device.h" // // Defines // #define PASS 0U #define FAIL 1U #define ISR_LOOP_TIMEOUT 0x3U #define MASK_ALL_BUT_FLASH_ERR 0x3F6UL // // Flash ECC Logic test values // #define TEST_FLASH_DATAL ((uint32_t)(TEST_FLASH_DATA64)) #define TEST_FLASH_DATAH ((uint32_t)(TEST_FLASH_DATA64 >> 32)) #define TEST_FLASH_ADDR 0x00090000UL #define TEST_FLASH_DATA64 0xFEDCBA0987654321ULL // // Typedefs // typedef enum { TEST_ECC_BLOCK_LOW = 0x00, //!< Low 64-bit block TEST_ECC_BLOCK_HIGH = 0x02 //!< High 64-bit block } ECCBlock; // // Globals // uint16_t calcECC; uint32_t result = FAIL; volatile bool nmiISRFlag; uint16_t nmiStatus; volatile bool errorISRFlag; uint16_t errorStatus; uint16_t errorCount; uint32_t errorType; uint64_t dataOut; // // Function Prototypes // __interrupt void nmiISR(void); __interrupt void corrErrorISR(void); uint16_t runCorrectableDataErrorTest(void); uint16_t runCorrectableECCErrorTest(void); uint16_t runUncorrectableErrorTest(void); void testECCBlock(uint64_t data, uint32_t address, ECCBlock eccBlock, uint16_t ecc); #pragma CODE_SECTION(testECCBlock, ".TI.ramfunc"); uint16_t calculateECC(uint32_t address, uint64_t data); // // Main // void main(void) { uint16_t failCount; // // Initialize device clock and peripherals. // Device_init(); // // Initialize PIE and clear PIE registers. Disables CPU interrupts. // Interrupt_initModule(); // // Initialize the PIE vector table with pointers to the shell Interrupt // Service Routines (ISR). // Interrupt_initVectorTable(); // // Clear all the NMI and Flash error status flags. // EALLOW; HWREG(FLASH0ECC_BASE + FLASH_O_ERR_STATUS_CLR) = 0xFFFFFFFFU; HWREG(FLASH0ECC_BASE + FLASH_O_ERR_INTCLR) = 0xFFFFFFFFU; EDIS; SysCtl_clearAllNMIFlags(); // // Plug the NMI and Flash correctable error ISRs. // Interrupt_register(INT_NMI, &nmiISR); Interrupt_register(INT_FLASH_CORR_ERR, corrErrorISR); Interrupt_enable(INT_FLASH_CORR_ERR); // // Enabling the NMI global interrupt (typically already enabled by boot ROM // or GEL file). // SysCtl_enableNMIGlobalInterrupt(); // // Enable Global Interrupt (INTM) and Real Time interrupt (DBGM). // EINT; ERTM; // // Calculate ECC on test data. // calcECC = calculateECC(TEST_FLASH_ADDR, TEST_FLASH_DATA64); // // Enable ECC. // // Flash_enableECC(FLASH0ECC_BASE); Flash_disableECC(FLASH0ECC_BASE); // // Test detection of correctable ECC errors in Flash data bits. // failCount = runCorrectableDataErrorTest(); // // Test detection of correctable ECC errors in Flash ECC bits. // failCount += runCorrectableECCErrorTest(); // // Test detection of uncorrectable ECC errors in Flash. // failCount += runUncorrectableErrorTest(); // // Status of a successful handling of the ECC errors. // if(failCount != 0U) { result = FAIL; } else { result = PASS; } // // Loop here and check results in the CCS Expressions view. // while(1); } // // nmiISR - The interrupt service routine called when the NMI is generated // on an uncorrectable Flash ECC error. // __interrupt void nmiISR(void) { // // Set a flag indicating the NMI ISR occurred and get the NMI status. // nmiISRFlag = true; nmiStatus = SysCtl_getNMIFlagStatus(); // // Record the error test status. // errorStatus = Flash_getECCTestStatus(FLASH0ECC_BASE); // // Clear all the flags. // EALLOW; HWREG(FLASH0ECC_BASE + FLASH_O_ERR_STATUS_CLR) = 0xFFFFFFFFU; EDIS; Flash_clearUncorrectableInterruptFlag(FLASH0ECC_BASE); SysCtl_clearAllNMIFlags(); } // // corrErrorISR - The interrupt service routine called when the correctable // error count hits the configured interrupt threshold. // __interrupt void corrErrorISR(void) { // // Set a flag indicating the RAM error ISR occurred. // errorISRFlag = true; // // Record the type of error injected, the status flags, the corrected data, // and the number of single-bit ECC errors detected. // errorType = Flash_getECCTestSingleBitErrorType(FLASH0ECC_BASE); errorStatus = Flash_getECCTestStatus(FLASH0ECC_BASE); dataOut = ((uint64_t)Flash_getTestDataOutHigh(FLASH0ECC_BASE) << 32) | (uint64_t)Flash_getTestDataOutLow(FLASH0ECC_BASE); errorCount = Flash_getErrorCount(FLASH0ECC_BASE); // // Clear all the flags. // EALLOW; HWREG(FLASH0ECC_BASE + FLASH_O_ERR_STATUS_CLR) = 0xFFFFFFFFU; EDIS; Flash_clearSingleErrorInterruptFlag(FLASH0ECC_BASE); Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP12); } // // runCorrectableDataErrorTest - Runs a test of the correctable data error // detection and correction as well as the error interrupt threshold. // uint16_t runCorrectableDataErrorTest(void) { uint16_t fail = 0U; uint16_t timeout= ISR_LOOP_TIMEOUT; // // Clear error status variables. // errorISRFlag = false; errorStatus = 0U; errorType = 0U; errorCount = 0U; dataOut = 0U; // // Configure the correctable error interrupt threshold to >1 errors. // Flash_setErrorThreshold(FLASH0ECC_BASE, 1U); // // Flip a single bit in the data to inject a correctable error for the // test to detect. // testECCBlock(TEST_FLASH_DATA64 ^ 0x80U, TEST_FLASH_ADDR, TEST_ECC_BLOCK_LOW, calcECC); // // Generate another single bit error to increase the count above the // threshold. // testECCBlock(TEST_FLASH_DATA64 ^ ((uint64_t)0x1U << 37), TEST_FLASH_ADDR, TEST_ECC_BLOCK_LOW, calcECC); // // Wait until the error interrupt is fired. // while((errorISRFlag != true) && (timeout != 0U)) { timeout--; } // // Check if interrupt occurred as expected or if the loop timed out. // if(timeout == 0U) { fail++; } // // Check if the appropriate correctable Flash error flag was set. // if((errorStatus & FLASH_SINGLE_ERROR) != FLASH_SINGLE_ERROR) { fail++; } // // Check if the error count is 2. // if(errorCount != 2U) { fail++; } // // Check if the error was a data error. // if(errorType != FLASH_DATA_ERR) { fail++; } // // Check that the data value was corrected properly. // if(dataOut != TEST_FLASH_DATA64) { fail++; } return(fail); } // // runCorrectableECCErrorTest - Runs a test of the correctable error detection. // uint16_t runCorrectableECCErrorTest(void) { uint16_t fail = 0U; uint16_t timeout= ISR_LOOP_TIMEOUT; // // Clear error status variables. // errorISRFlag = false; errorStatus = 0U; errorType = 0U; // // Configure the correctable error interrupt threshold to >0 errors. // Flash_setErrorThreshold(FLASH0ECC_BASE, 0U); // // Flip a single bit in the data to inject a correctable error for the // test to detect. // testECCBlock(TEST_FLASH_DATA64, TEST_FLASH_ADDR, TEST_ECC_BLOCK_LOW, calcECC ^ 0x2U); // // Wait until the error interrupt is fired. // while((errorISRFlag != true) && (timeout != 0U)) { timeout--; } // // Check if interrupt occurred as expected or if the loop timed out. // if(timeout == 0U) { fail++; } // // Check if the appropriate correctable Flash error flag was set. // if((errorStatus & FLASH_SINGLE_ERROR) != FLASH_SINGLE_ERROR) { fail++; } // // Check if the error was an ECC error. // if(errorType != FLASH_ECC_ERR) { fail++; } return(fail); } // // runUncorrectableErrorTest - Runs a test of the uncorrectable data error // detection and associated NMI generation. // uint16_t runUncorrectableErrorTest(void) { uint16_t fail = 0U; uint16_t timeout= ISR_LOOP_TIMEOUT; // // Clear error status variables. // nmiISRFlag = false; nmiStatus = 0U; errorStatus = 0U; // // Flip multiple bits in the data to inject an uncorrectable error for the // test to detect. // testECCBlock(TEST_FLASH_DATA64 ^ 0x30U, TEST_FLASH_ADDR, TEST_ECC_BLOCK_LOW, calcECC); // // Wait until the NMI is fired. // while((nmiISRFlag != true) && (timeout != 0U)) { timeout--; } // // Check if interrupt occurred as expected or if the loop timed out. // if(timeout == 0U) { fail++; } // // Check if the NMI triggered was due to an uncorrectable Flash error. // if((nmiStatus & SYSCTL_NMI_FLUNCERR) != SYSCTL_NMI_FLUNCERR) { fail++; } // // Check if the appropriate uncorrectable Flash error flag was set. // if((errorStatus & FLASH_UNC_ERROR) != FLASH_UNC_ERROR) { fail++; } return(fail); } // // testECCBlock - Sets up the ECC test registers and performs the ECC // calculation to detect and error if one is injected. // void testECCBlock(uint64_t data, uint32_t address, ECCBlock eccBlock, uint16_t ecc) { // // Write 128-bit flash address in FADDR_TEST // Flash_setECCTestAddress(FLASH0ECC_BASE, address); // // Write lower 32 bits of data in FDATAL_TEST // Flash_setDataLowECCTest(FLASH0ECC_BASE, (uint32_t)data); // // Write upper 32 bits of data in FDATAH_TEST // Flash_setDataHighECCTest(FLASH0ECC_BASE, (uint32_t)(data >> 32)); // // Write corresponding ECC in the FECC_TEST // Insert double bit error in flash ecc // Flash_setECCTestECCBits(FLASH0ECC_BASE, ecc); // // Select the ECC block to be tested. Only one of the SECDED modules (out // of the two SECDED modules that work on lower 64 bits and upper 64 bits // of a read 128-bit data) at a time can be tested. // if(eccBlock == TEST_ECC_BLOCK_LOW) { Flash_selectLowECCBlock(FLASH0ECC_BASE); } else { Flash_selectHighECCBlock(FLASH0ECC_BASE); } // // Enable the ECC Test Mode // Flash_enableECCTestMode(FLASH0ECC_BASE); // // Perform ECC calculation // Flash_performECCCalculation(FLASH0ECC_BASE); // // Disable the ECC Test Mode // Flash_disableECCTestMode(FLASH0ECC_BASE); } // // calcECC - Calculate the ECC for an address/data pair. This code comes from // the ECC Calculation Algorithm appendix of the Flash API reference // guide (SPNU628). If you are using the Flash API in your code, you // could use Fapi_calculateEcc() instead. // uint16_t calculateECC(uint32_t address, uint64_t data) { const uint32_t addrSyndrome[8] = {0x554EAU, 0x0BAD1U, 0x2A9B5U, 0x6A78DU, 0x19F83U, 0x07F80U, 0x7FF80U, 0x0007FU}; const uint64_t dataSyndrome[8] = {0xB4D1B4D14B2E4B2EU, 0x1557155715571557U, 0xA699A699A699A699U, 0x38E338E338E338E3U, 0xC0FCC0FCC0FCC0FCU, 0xFF00FF00FF00FF00U, 0xFF0000FFFF0000FFU, 0x00FFFF00FF0000FFU}; const uint16_t parity = 0xFCU; uint64_t xorData; uint32_t xorAddr; uint16_t bit, eccBit, eccVal; // // Extract bits "20:2" of the address // address = (address >> 2) & 0x7FFFFU; // // Compute the ECC one bit at a time. // eccVal = 0U; for (bit = 0U; bit < 8U; bit++) { // // Apply the encoding masks to the address and data // xorAddr = address & addrSyndrome[bit]; xorData = data & dataSyndrome[bit]; // // Fold the masked address into a single bit for parity calculation. // The result will be in the LSB. // xorAddr = xorAddr ^ (xorAddr >> 16); xorAddr = xorAddr ^ (xorAddr >> 8); xorAddr = xorAddr ^ (xorAddr >> 4); xorAddr = xorAddr ^ (xorAddr >> 2); xorAddr = xorAddr ^ (xorAddr >> 1); // // Fold the masked data into a single bit for parity calculation. // The result will be in the LSB. // xorData = xorData ^ (xorData >> 32); xorData = xorData ^ (xorData >> 16); xorData = xorData ^ (xorData >> 8); xorData = xorData ^ (xorData >> 4); xorData = xorData ^ (xorData >> 2); xorData = xorData ^ (xorData >> 1); // // Merge the address and data, extract the ECC bit, and add it in // eccBit = ((uint16_t)xorData ^ (uint16_t)xorAddr) & 0x0001U; eccVal |= eccBit << bit; } // // Handle the bit parity. For odd parity, XOR the bit with 1 // eccVal ^= parity; return eccVal; } // // End of File //
e2e.ti.com/.../sdl_5F00_ex_5F00_flash_5F00_ecc_5F00_test.7z
Vamsi、
我在这里发布项目、您需要 在 nmiISR 中设置一个断点以 进行重现。