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.
Hi,
My customer implement SRAM self test using Diagnostic Library 2.4.0.
Check RAM ECC:
boolean retVal; SL_SelfTest_Result result; retVal = SL_SelfTest_SRAM(SRAM_ECC_ERROR_FORCING_1BIT, TRUE, &result); if(retVal == false){while(1);} if(result != ST_PASS) { /* Test fail */ while(1); } retVal = SL_SelfTest_SRAM(SRAM_ECC_ERROR_FORCING_2BIT, TRUE, &result); if(retVal == false){while(1);} if(result != ST_PASS) { /* Test fail */ while(1); }
boolean retVal; SL_SelfTest_Result result; /* Flash test needs to be run from a RAM location. Copy flash test to RAM */ uint32 i; uint32 size=(uint32)&ulHighHandlerSize; for(i=0;i<size;i++) { ((char *)&ulHighHandlerStartAddr)[i] =((char *)&ulHighHandlerLoadStart)[i]; } retVal = SL_SelfTest_Flash(FLASH_ECC_TEST_MODE_1BIT, TRUE, &result); if(retVal == false){while(1);} if(result != ST_PASS) { /* Test fail */ while(1); } retVal = SL_SelfTest_Flash(FLASH_ECC_TEST_MODE_2BIT, TRUE, &result); if(retVal == false){while(1);} if(result != ST_PASS) { /* Test fail */ while(1); }
if(result != ST_PASS)
{
/* Test fail */
while(1);
}
The code seems correct. What is missing here?
Thanks and regards,
Koichiro Tashiro
Hi Koichiro-san,
When the test completes, are the error flags in RAM status register and ESM status register set correctly?
For SRAM_ECC_ERROR_FORCING_2BIT test, the ESM 2.7, and RAMERRSTATUS[21:20] should be set. Can you please check bit is not set after your self-test?
Hi QJ,
When the test completes, are the error flags in RAM status register and ESM status register set correctly?
After
retVal = SL_SelfTest_SRAM(SRAM_ECC_ERROR_FORCING_1BIT, TRUE, &result);
retVal = 0 and
esm1_stat1 : 00000000
esm1_stat2 : 00000000
esm1_stat3 : 00000008
L2ramw_RamErrStat:00000080 00000000 00000000 00000000
After
retVal = SL_SelfTest_SRAM(SRAM_ECC_ERROR_FORCING_2BIT, TRUE, &result);
retVal =0 and
esm1_stat1 : 00000000
esm1_stat2 : 00000000
esm1_stat3 : 00000008
L2ramw_RamErrStat:00000080 00000000 00000000 00000000
Thanks and regards,
Koichiro Tashiro
Hi Koichiro-san,
Just run a test using the SDL on RM57Lx HDK:
1. retVal = SL_SelfTest_SRAM(SRAM_ECC_ERROR_FORCING_1BIT, TRUE, &failInfoTCMRAM);
ESMSR2 = 0x80 --> ESM 2.7 = 1
DRSE=1, Diagnostic Read Single-bit Error.
and DWSE=1, Diagnostic Write Single-bit Error
2. retVal = SL_SelfTest_SRAM(SRAM_ECC_ERROR_FORCING_2BIT, TRUE, &failInfoTCMRAM);
DRDE=1, and DWDE=1 (RAMERRSTATUS register)
Hi QJ,
Thanks for trying.
Your results are different than what customer got.
I guess something different between your test and customer's.
Could you send me your source code?
Thanks and regards,
Koichiro Tashiro
Hi Koichiro-san,
I use the example code in the SDL folder. I added two function calls in the main():
I set two breakpoints at those two function calls, and step into the SL_Selftest_SRAM(..), and check the ESM status registers and L2RAM Error register before the error flags are cleared.
To simply my test, I disable the CPU selftest in _c_int00().
This is the app_main_NoOS.c and HL_sys_startup.c used for my test:
All edited code has comment of "//QJ"
/** @file HL_sys_startup.c * @brief Startup Source File * @date 02-Mar-2016 * @version 04.05.02 * * This file contains: * - Include Files * - Type Definitions * - External Functions * - VIM RAM Setup * - Startup Routine * . * which are relevant for the Startup. */ /* * Copyright (C) 2009-2016 Texas Instruments Incorporated - 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. * */ /* USER CODE BEGIN (0) */ /* USER CODE END */ /* Include Files */ #include "HL_sys_common.h" #include "HL_system.h" #include "HL_sys_vim.h" #include "HL_sys_core.h" #include "HL_esm.h" #include "HL_sys_mpu.h" /* USER CODE BEGIN (1) */ #include "HL_sys_selftest.h" #include "esm_application_callback.h" #include "sl_priv.h" /* USER CODE END */ /* USER CODE BEGIN (2) */ volatile uint64 crcAtInit_VIMRAM = 0; volatile uint64 crcAtInit_FLASH = 0; /* USER CODE END */ /* External Functions */ /*SAFETYMCUSW 218 S MR:20.2 <APPROVED> "Functions from library" */ extern void __TI_auto_init(void); /*SAFETYMCUSW 354 S MR:NA <APPROVED> " Startup code(main should be declared by the user)" */ extern void main(void); /*SAFETYMCUSW 122 S MR:20.11 <APPROVED> "Startup code(exit and abort need to be present)" */ /*SAFETYMCUSW 354 S MR:NA <APPROVED> " Startup code(Extern declaration present in the library)" */ extern void exit(int _status); /* USER CODE BEGIN (3) */ void afterSTC(void); SL_ResetReason resetReason; /* Reset reason */ uint32 cnt; //added by QJ /* USER CODE END */ /* Startup Routine */ void _c_int00(void); /* USER CODE BEGIN (4) */ extern uint32 ulHighHandlerLoadStart; extern uint32 ulHighHandlerLoadEnd; extern uint32 ulHighHandlerSize; extern uint32 ulHighHandlerStartAddr; extern uint32 ulHighHandlerEndAddr; SL_STC_Config stcSelfTestConfig; /* STC Configuration */ /* USER CODE END */ #pragma CODE_STATE(_c_int00, 32) #pragma INTERRUPT(_c_int00, RESET) #pragma WEAK(_c_int00) void _c_int00(void) { /* USER CODE BEGIN (5) */ #if 0 /* USER CODE END */ /* Initialize Core Registers to avoid CCM Error */ _coreInitRegisters_(); /* Reset handler: the following instructions read from the system exception status register * to identify the cause of the CPU reset. */ switch(getResetSource()) { case POWERON_RESET: case DEBUG_RESET: case EXT_RESET: /* USER CODE BEGIN (6) */ #endif /* Initialize Core Registers to avoid CCM Error */ SL_Init_R5Registers(); /* Initialize Stack Pointers * The SL_Init_ResetReason API (and the correspondig HALCoGen getresetsource API) is a C function which uses stack. * Stack must be setup correctly before calling this function.*/ SL_Init_StackPointers(); /* Enable CPU Event Export */ /* This allows the CPU to signal any single-bit or double-bit errors detected * by its ECC logic for accesses to program flash or data RAM. */ /* NOTE - needs to be called on every reset */ _SL_Init_EnableEventExport(); // cnt = 0; // while(cnt == 0); resetReason = SL_Init_ResetReason(); switch(resetReason) { case RESET_TYPE_POWERON: case RESET_TYPE_DEBUG: case RESET_TYPE_EXTRST: case RESET_TYPE_EXTRST_NERROR: #if 0 /* USER CODE END */ /* Initialize L2RAM to avoid ECC errors right after power on */ _memInit_(); /* USER CODE BEGIN (7) */ #endif /* Initialize L2RAM to avoid ECC errors right after power on * This function uses the system module's hardware for auto-initialization of memories and their * associated protection schemes. The CPU RAM is initialized by setting bit 0 of the MSIENA register. * Hence the value 0x1 passed to the function. * This function will initialize the entire CPU RAM and the corresponding ECC locations. */ SL_Init_Memory(RAMTYPE_RAM); /* USER CODE END */ /* USER CODE BEGIN (8) */ #if 0 /* USER CODE END */ /* Initialize Stack Pointers */ _coreInitStackPointer_(); /* USER CODE BEGIN (9) */ #endif #if 0 /* USER CODE END */ /* Enable CPU Event Export */ /* This allows the CPU to signal any single-bit or double-bit errors detected * by its ECC logic for accesses to program flash or data RAM. */ _coreEnableEventBusExport_(); /* USER CODE BEGIN (10) */ #endif /* Enable CPU Event Export */ /* This allows the CPU to signal any single-bit or double-bit errors detected * by its ECC logic for accesses to program flash or data RAM. */ //_SL_Init_EnableEventExport(); /* USER CODE END */ /* Check if there were ESM group3 errors during power-up. * These could occur during eFuse auto-load or during reads from flash OTP * during power-up. Device operation is not reliable and not recommended * in this case. */ if ((esmREG->SR1[2]) != 0U) { while(1); //ESM group3 error } /* Initialize System - Clock, Flash settings with Efuse self check */ systemInit(); /* USER CODE BEGIN (11) */ #if 0 /* USER CODE END */ /* Enable IRQ offset via Vic controller */ _coreEnableIrqVicOffset_(); /* Initialize VIM table */ vimInit(); /* USER CODE BEGIN (12) */ /* USER CODE END */ /* Configure system response to error conditions signaled to the ESM group1 */ /* This function can be configured from the ESM tab of HALCoGen */ esmInit(); /* USER CODE BEGIN (13) */ #endif #if 0 /* USER CODE END */ break; case OSC_FAILURE_RESET: /* USER CODE BEGIN (14) */ #endif break; case RESET_TYPE_OSC_FAILURE: #if 0 /* USER CODE END */ break; case WATCHDOG_RESET: /* USER CODE BEGIN (15) */ #endif break; case RESET_TYPE_WATCHDOG: #if 0 /* USER CODE END */ break; case CPU0_RESET: case CPU1_RESET: /* USER CODE BEGIN (16) */ #endif break; case RESET_TYPE_CPU0: case RESET_TYPE_CPU1: #if 0 //QJ Wang /* Reset caused due to CPU reset. CPU reset can be caused by CPU self-test completion, or by toggling the "CPU RESET" bit of the CPU Reset Control Register. */ /* reset could be caused by stcSelfCheck run or by an actual CPU self-test run */ /* check if this was an stcSelfCheck run */ #if defined(_TMS570LS31x_) || defined(_TMS570LS12x_) || defined(_RM48x_) || defined(_RM46x_) || defined(_RM42x_) || defined(_TMS570LS04x_) if ((stcREG->STCSCSCR & 0xFU) == 0xAU) { /* check if the self-test fail bit is set */ if ((stcREG->STCGSTAT & 0x3U) != 0x3U) #endif #if defined(_TMS570LC43x_) || defined(_RM57Lx_) if ((stcREG1->STCSCSCR & 0xFU) == 0xAU) { /* check if the self-test fail bit is set */ if ((stcREG1->STCGSTAT & 0x3U) != 0x3U) #endif { for(;;) { } } /* STC self-check has passed */ else { /* clear self-check mode */ #if defined(_TMS570LS31x_) || defined(_TMS570LS12x_) || defined(_RM48x_) || defined(_RM46x_) || defined(_RM42x_) || defined(_TMS570LS04x_) stcREG->STCSCSCR = 0x05U; /* clear STC global status flags */ stcREG->STCGSTAT = 0x3U; #endif #if defined(_TMS570LC43x_) || defined(_RM57Lx_) stcREG1->STCSCSCR = 0x05U; /* clear STC global status flags */ stcREG1->STCGSTAT = 0x3U; #endif /* clear ESM group1 channel 27 status flag */ esmREG->SR1[0U] = 0x08000000U; /* Start CPU Self-Test */ /*there is no alternate usercode place holder to place the safety library api so this block of code can * get overwritten on helcogen code regeneration*/ /*********************************************************************************************************/ /*cpuSelfTest(STC_INTERVAL, STC_MAX_TIMEOUT, TRUE);*/ stcSelfTestConfig.stcClockDiv = 0; /* STC Clock divider = 1 */ stcSelfTestConfig.intervalCount = 1; /* One interval only */ stcSelfTestConfig.restartInterval0 = TRUE; /* Start from interval 0 */ stcSelfTestConfig.timeoutCounter = 0xFFFFFFFF; /* Timeout counter*/ _SL_HoldNClear_nError(); /* mask vim interrupts before running STC */ vimREG->REQMASKCLR0 = 0xFFFFFFFFu; vimREG->REQMASKCLR1 = 0xFFFFFFFFu; vimREG->REQMASKCLR2 = 0xFFFFFFFFu; vimREG->REQMASKCLR3 = 0xFFFFFFFFu; /* ensure no pending ESM GRP2 errors before running STC */ if(esmREG->SSR2 == 0u) #if defined(_TMS570LS31x_) || defined(_TMS570LS12x_) || defined(_RM48x_) || defined(_RM46x_) || defined(_RM42x_) || defined(_TMS570LS04x_) {SL_SelfTest_STC(STC_RUN, TRUE, &stcSelfTestConfig);} #endif #if defined(_TMS570LC43x_) || defined(_RM57Lx_) {SL_SelfTest_STC(STC1_RUN, TRUE, &stcSelfTestConfig);} #endif /*********************************************************************************************************/ } } /* CPU reset caused by CPU self-test completion */ #if defined(_TMS570LS31x_) || defined(_TMS570LS12x_) || defined(_RM48x_) || defined(_RM46x_) || defined(_RM42x_) || defined(_TMS570LS04x_) else if ((stcREG->STCGSTAT & 0x1U) == 0x1U) { /* Self-Test Fail flag is set */ if ((stcREG->STCGSTAT & 0x2U) == 0x2U) { #endif #if defined(_TMS570LC43x_) || defined(_RM57Lx_) else if ((stcREG1->STCGSTAT & 0x1U) == 0x1U) { /* Self-Test Fail flag is set */ if ((stcREG1->STCGSTAT & 0x2U) == 0x2U) { #endif for(;;) { } } /* CPU self-test completed successfully */ else { /* clear STC global status flag */ stcREG1->STCGSTAT = 0x1U; /* Continue start-up sequence after CPU STC completed */ afterSTC(); } } /* CPU reset caused by software writing to CPU RESET bit */ else #endif //QJ Wang { /* Add custom routine here to handle the case where software causes CPU reset */ /* USER CODE END */ /* USER CODE BEGIN (17) */ #if 0 /* USER CODE END */ /* Initialize Stack Pointers */ _coreInitStackPointer_(); /* USER CODE BEGIN (18) */ #endif #if 0 /* USER CODE END */ /* Enable CPU Event Export */ /* This allows the CPU to signal any single-bit or double-bit errors detected * by its ECC logic for accesses to program flash or data RAM. */ _coreEnableEventBusExport_(); /* USER CODE BEGIN (19) */ #endif /* Enable CPU Event Export */ /* This allows the CPU to signal any single-bit or double-bit errors detected * by its ECC logic for accesses to program flash or data RAM. */ _SL_Init_EnableEventExport(); #if 0 /* USER CODE END */ break; case SW_RESET: /* USER CODE BEGIN (20) */ #endif } break; case RESET_TYPE_SWRST: break; case RESET_TYPE_ICSTRST: if(!SL_SelfTest_Status_MemIntrcntSelftest()) { while(1); } //Memory Interconnect Error /* USER CODE END */ break; default: /* USER CODE BEGIN (21) */ /* USER CODE END */ break; } /* USER CODE BEGIN (22) */ #if 0 //QJ if(RESET_TYPE_DEBUG != resetReason) { if(RESET_TYPE_ICSTRST != resetReason) { /* Memory interconnect selftest */ SL_SelfTest_MemoryInterconnect(MEMINTRCNT_SELFTEST); } /* Make sure that the CPU self-test controller can actually detect a fault inside CPU */ stcSelfTestConfig.stcClockDiv = 0; /* STC Clock divider = 1 */ stcSelfTestConfig.intervalCount = 1; /* One interval only */ stcSelfTestConfig.restartInterval0 = TRUE; /* Start from interval 0 */ stcSelfTestConfig.timeoutCounter = 0xFFFFFFFF; /* Timeout counter*/ _SL_HoldNClear_nError(); /* mask vim interrupts before running STC */ vimREG->REQMASKCLR0 = 0xFFFFFFFFu; vimREG->REQMASKCLR1 = 0xFFFFFFFFu; vimREG->REQMASKCLR2 = 0xFFFFFFFFu; vimREG->REQMASKCLR3 = 0xFFFFFFFFu; /* ensure no pending ESM GRP2 errors before running STC */ if(esmREG->SSR2 == 0u) { SL_SelfTest_STC(STC1_COMPARE_SELFCHECK, TRUE, &stcSelfTestConfig); } else { while(1); //ESM Group2 error } } else #endif //QJ { afterSTC(); } } void afterSTC(void) { /* Enable IRQ offset via Vic controller */ _coreEnableIrqVicOffset_(); /* Initialize VIM table */ vimInit(); /* Configure system response to error conditions signaled to the ESM group1 */ /* This function can be configured from the ESM tab of HALCoGen */ esmInit(); /* USER CODE END */ _mpuInit_(); /* USER CODE BEGIN (23) */ /* USER CODE END */ _cacheEnable_(); /* USER CODE BEGIN (24) */ /* USER CODE END */ /* USER CODE BEGIN (25) */ /* USER CODE END */ /* initialize global variable and constructors */ __TI_auto_init(); /* USER CODE BEGIN (26) */ /* Initialize EPC */ epcInit(); /* enable DMA ECC */ sl_dmaREG->DMAPCR |= (uint32)0xAU; /* initialise DMA RAM */ SL_Init_Memory(RAMTYPE_DMA_RAM); /* Initialise ADC */ adcInit(); /* Initialise ADC SRAM */ SL_Init_Memory(RAMTYPE_MIBADC1_RAM); SL_Init_Memory(RAMTYPE_MIBADC2_RAM); /* Initialise MIBSPI */ mibspiInit(); /* Initialise MIBSPI SRAM */ SL_Init_Memory(RAMTYPE_MIBSPI1_RAM); SL_Init_Memory(RAMTYPE_MIBSPI2_RAM); SL_Init_Memory(RAMTYPE_MIBSPI3_RAM); SL_Init_Memory(RAMTYPE_MIBSPI4_RAM); SL_Init_Memory(RAMTYPE_MIBSPI5_RAM); /* Initialise SCI */ sciInit(); /* Initialise CAN */ canInit(); /* Initialise CAN SRAM */ SL_Init_Memory(RAMTYPE_DCAN1_RAM); SL_Init_Memory(RAMTYPE_DCAN2_RAM); SL_Init_Memory(RAMTYPE_DCAN3_RAM); SL_Init_Memory(RAMTYPE_DCAN4_RAM); SL_ESM_Init(ESM_ApplicationCallback); _enable_interrupt_(); uint32 i; uint32 size=(uint32)&ulHighHandlerSize; for(i=0;i<size;i++) { ((char *)&ulHighHandlerStartAddr)[i] =((char *)&ulHighHandlerLoadStart)[i]; } /* Boot time MIBSPI Analog Loopback Test */ SL_SelfTest_MibSPI(MIBSPI_ANALOG_LOOPBACK_TEST,SL_MIBSPI2); SL_SelfTest_MibSPI(MIBSPI_ANALOG_LOOPBACK_TEST,SL_MIBSPI4); SL_SelfTest_MibSPI(MIBSPI_ANALOG_LOOPBACK_TEST,SL_MIBSPI3); SL_SelfTest_MibSPI(MIBSPI_ANALOG_LOOPBACK_TEST,SL_MIBSPI1); SL_SelfTest_MibSPI(MIBSPI_ANALOG_LOOPBACK_TEST,SL_MIBSPI5); //Boot time Software test of VIM functionality SL_SelfTest_VIM(VIM_SOFTWARE_TEST); //Boot time Software test of DMA functionality SL_SelfTest_DMA(DMA_SOFTWARE_TEST); checkPLL1Slip(); checkPLL2Slip(); /* USER CODE END */ /* call the application */ /*SAFETYMCUSW 296 S MR:8.6 <APPROVED> "Startup code(library functions at block scope)" */ /*SAFETYMCUSW 326 S MR:8.2 <APPROVED> "Startup code(Declaration for main in library)" */ /*SAFETYMCUSW 60 D MR:8.8 <APPROVED> "Startup code(Declaration for main in library;Only doing an extern for the same)" */ main(); /* USER CODE BEGIN (27) */ /* USER CODE END */ /*SAFETYMCUSW 122 S MR:20.11 <APPROVED> "Startup code(exit and abort need to be present)" */ exit(0); /* USER CODE BEGIN (28) */ /* USER CODE END */ } /* USER CODE BEGIN (29) */ /* USER CODE END */ /* USER CODE BEGIN (30) */ /* USER CODE END */
Hi QJ,
Unfortunately SL_SelfTest_Flash() does not pass in customer environment.
The code stops at below:
retVal = SL_SelfTest_Flash(FLASH_ECC_TEST_MODE_2BIT, TRUE, &result); if(retVal == false){while(1);} if(result != ST_PASS) { /* Test fail */ while(1); <== code stops here
if (BIT(ESM_G2ERR_CR5_BUSERR) == (sl_esmREG->SSR2 & BIT(ESM_G2ERR_CR5_BUSERR))) { /* Clear nError */ _SL_HoldNClear_nError(); sl_esmREG->SSR2 = BIT(ESM_G2ERR_CR5_BUSERR); *flash_stResult = ST_PASS; } else { *flash_stResult = ST_FAIL; <== ST_FAIL returned here } }
Can you disable the pipeline before triggering the diagnostics and re-enable it after the test?
sl_flashWREG->FDIAGCTRL |= F021F_FDIAGCTRL_DIAG_TRIG;
/* disable pipeline mode*/
sl_flashWREG->FRDCNTL &= 0xFFFFFFFE;
flashread = *(volatile uint32 *)flashBadECC2;
/*Enable pipeline mode*/
sl_flashWREG->FRDCNTL |= 0x01;