Hello,
My project needs to capture the SRAM non-correctable ECC event when the SRAM is corrupt for function safety. But now I have two problems when I use ERM to implement it.
My solution is as follows:
1. Enable the ERM CH0 to capture the SRAM_L non-correctable ECC event;
2. Enable the ERM CH1 to capture the SRAM_U non-correctable ECC event;
3. The vector table is placed in the beginning of SRAM_L(i.e. __flash_vector_table__ is not defined) and some
time-critical codes also run in SRAM_L. All the variables are placed in SRAM_U;
4. The EIM is also used to confirm that the ERM is working properly by calling the following function
ERM_CheckByEIM() every 100ms in which the single error is injected into SRAM_L & SRAM_U by EIM.
5. SCST_Test() from SCST library is called every 100ms;
The problems are as follows:
1. Problem 1: The ERM reports that SRAM_L generates the non-correctable ECC event, but SRAM_U is OK;
2. Problem 2: If the ERM CH0 is not enabled for SRAM_L non-correctable ECC event capture and RCM is enabled to delay the s/w reset(The register bits 'SIM->CHIPCTL.SRAML_RETEN/SRAMU_RETEN' have been set in SystemInit() after MCU reset and cleared in the ISR of RCM), the ERM reports that the SRAM_U has the non-correctable ECC event too.
So I'm confused which causes the problems.
/*------------------------------------------------------------------------------------------------------------------------*/
SCST_PLACE_IN_SECTION(safety_func_code) // This function is placed in SRAM_L to run.
void ERM_CheckByEIM(void)
{
uint32_t *p;
volatile uint32_t wReadData, wErrAddr;
bool bTest1OK = false, bTest2OK = false;
/*--- Read the the SRAM_L/SRAM_U to see the error. ---*/
__disable_irq();
/* Initialize the EIM for the single error injection. */
EIM_DRV_Init(INST_EIM0, EIM_CHANNEL_COUNT0, eim1_ChannelConfig0);
/* Clear the single error flag of CH0/1 */
ERM_DRV_ClearEvent(INST_ERM0, 0, ERM_EVENT_SINGLE_BIT);
ERM_DRV_ClearEvent(INST_ERM0, 1, ERM_EVENT_SINGLE_BIT);
/* Read the SRAM_L twice to detect the sigle error by ERM. */
p = (uint32_t *)0x1FFFFF00;
wReadData = *p;
wReadData = *p;
/* Check the ERM sigle bit error flag to valiate that the ERM is working properly. */
if (ERM_DRV_GetErrorDetail(INST_ERM0, 0, (uint32_t *)&wErrAddr) == ERM_EVENT_SINGLE_BIT)
{
if (wErrAddr == 0x1FFFFF00) bTest1OK = true;
}
/* Read the SRAM_U twice to detect the sigle error by ERM. */
p = (uint32_t *)0x20000000;
wReadData = *p;
wReadData = *p;
/* Check the ERM sigle bit error flag to valiate that the ERM is working properly. */
if (ERM_DRV_GetErrorDetail(INST_ERM0, 1, (uint32_t *)&wErrAddr) == ERM_EVENT_SINGLE_BIT)
{
if (wErrAddr == 0x20000000) bTest2OK = true;
}
/* Clear the single error flag of CH0/1 */
ERM_DRV_ClearEvent(INST_ERM0, 0, ERM_EVENT_SINGLE_BIT);
ERM_DRV_ClearEvent(INST_ERM0, 1, ERM_EVENT_SINGLE_BIT);
__enable_irq();
/*----------------------------------------------------*/
/* Disable the EIM. */
EIM_DRV_Deinit(INST_EIM0);
/* Reset the MCU if the ERM is not working properly. */
if ((bTest1OK == false) || (bTest2OK == false)) NVIC_SystemReset(); /* S/W reset */
}
/*------------------------------------------------------------------------------------------------------------------------*/
Thanks & BRs,
David