2024-07-10 07:39 AM
Hi,
I have been trying to trigger a RAM ECC error for testing. I have referenced the code Here. However, I cant trigger an ecc error.
The plan is to read uninitialized ram as mentioned in AN5342. I am using SRAM(1-3) (Mem address 0x30000000 - 0x30047FFF). Please find the code snippet below.
RAMECC_HandleTypeDef hramecc2_m1;
RAMECC_HandleTypeDef hramecc2_m2;
RAMECC_HandleTypeDef hramecc2_m3;
RAMECC_HandleTypeDef hramecc2_m4;
RAMECC_HandleTypeDef hramecc2_m5;
#define SRAM_3_START (char*)0x30040000
#define SRAM_3_END (char*)0x30047FFF
#define SRAM_2_START (char*)0x30020000
#define SRAM_2_END (char*)0x3003FFFF
#define SRAM_1_START (char*)0x30000000
#define SRAM_1_END (char*)0x3001FFFF
static void MX_RAMECC_Init(void)
{
/* USER CODE BEGIN RAMECC_Init 0 */
/* USER CODE END RAMECC_Init 0 */
/* USER CODE BEGIN RAMECC_Init 1 */
/* USER CODE END RAMECC_Init 1 */
/** Initialize RAMECC2 M1 : SRAM1_0
*/
hramecc2_m1.Instance = RAMECC2_Monitor1;
if (HAL_RAMECC_Init(&hramecc2_m1) != HAL_OK)
{
Error_Handler();
}
/** Initialize RAMECC2 M2 SRAM1_1
*/
hramecc2_m2.Instance = RAMECC2_Monitor2;
if (HAL_RAMECC_Init(&hramecc2_m2) != HAL_OK)
{
Error_Handler();
}
/** Initialize RAMECC2 M3 : SRAM2_0
*/
hramecc2_m3.Instance = RAMECC2_Monitor3;
if (HAL_RAMECC_Init(&hramecc2_m3) != HAL_OK)
{
Error_Handler();
}
/** Initialize RAMECC2 M4 : SRAM2_1
*/
hramecc2_m4.Instance = RAMECC2_Monitor4;
if (HAL_RAMECC_Init(&hramecc2_m4) != HAL_OK)
{
Error_Handler();
}
/** Initialize RAMECC2 M5 : SRAM3
*/
hramecc2_m5.Instance = RAMECC2_Monitor5;
if (HAL_RAMECC_Init(&hramecc2_m5) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN RAMECC_Init 2 */
INIT_RAMECC(&hramecc2_m1);
INIT_RAMECC(&hramecc2_m2);
INIT_RAMECC(&hramecc2_m3);
INIT_RAMECC(&hramecc2_m4);
INIT_RAMECC(&hramecc2_m5);
/* NVIC configuration for RAMECC interrupt */
/* Priority: high-priority */
HAL_NVIC_SetPriority(ECC_IRQn, 1, 0);
HAL_NVIC_EnableIRQ(ECC_IRQn);
/* USER CODE END RAMECC_Init 2 */
}
void INIT_RAMECC(RAMECC_HandleTypeDef* hramecc){
/* Enable monitor notifications */
/* ECC single error notification and ECC double error notification */
if (HAL_RAMECC_EnableNotification(hramecc, (RAMECC_IT_MONITOR_SINGLEERR_R | RAMECC_IT_MONITOR_DOUBLEERR_R))!= HAL_OK)
{
Error_Handler();
}
/* Start Monitor : Enable latching failing information
Failing information : * Failing address
* Failing Data Low
* Failing Data High
* Hamming bits injected
*/
if (HAL_RAMECC_StartMonitor(hramecc) != HAL_OK)
{
Error_Handler();
}
}
int main(void)
{
/* USER CODE BEGIN 1 */
CPU_CACHE_Enable();
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_RAMECC_Init();
/* USER CODE BEGIN 2 */
/* Analyse all memory */
volatile uint32_t* mem_pointer = (volatile uint32_t*)SRAM_1_START;
while(1){
CurrentData = *mem_pointer;
mem_pointer++;
if(mem_pointer >= (volatile uint32_t*)SRAM_1_END){
break;
}
}
mem_pointer = (volatile uint32_t*)SRAM_2_START;
while(1){
CurrentData = *(mem_pointer);
mem_pointer++;
if(mem_pointer >= (volatile uint32_t*)SRAM_2_END){
break;
}
}
mem_pointer = (volatile uint32_t*)SRAM_3_START;
while(1){
CurrentData = *(mem_pointer);
mem_pointer++;
if(mem_pointer >= (volatile uint32_t*)SRAM_3_END){
break;
}
}
HAL_GPIO_TogglePin(GPIOI, GPIO_PIN_13);
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
if(HAL_RAMECC_IsECCSingleErrorDetected(&hramecc2_m1) |
HAL_RAMECC_IsECCSingleErrorDetected(&hramecc2_m2) |
HAL_RAMECC_IsECCSingleErrorDetected(&hramecc2_m3) |
HAL_RAMECC_IsECCSingleErrorDetected(&hramecc2_m4) |
HAL_RAMECC_IsECCSingleErrorDetected(&hramecc2_m5)){
HAL_GPIO_WritePin(GPIOJ, GPIO_PIN_2, GPIO_PIN_RESET);
}
if(HAL_RAMECC_IsECCDoubleErrorDetected(&hramecc2_m1) |
HAL_RAMECC_IsECCDoubleErrorDetected(&hramecc2_m2) |
HAL_RAMECC_IsECCDoubleErrorDetected(&hramecc2_m3) |
HAL_RAMECC_IsECCDoubleErrorDetected(&hramecc2_m4) |
HAL_RAMECC_IsECCDoubleErrorDetected(&hramecc2_m5)){
HAL_GPIO_WritePin(GPIOJ, GPIO_PIN_2, GPIO_PIN_RESET);
}
}
/* USER CODE END 3 */
}
Something I noticed is that even after a cold boot, the SRAM is still set to 0. Which would explain why an ecc error isn't triggered.
Any idea what Im missing? Thanks!
2024-09-20 12:10 PM
I am having the same issue. Were you ever able to figure this out?
2024-09-26 05:42 AM
Hello @snmunters and @20jmorrison
To generate a RAM ECC error, please follow these steps:
2024-09-26 01:31 PM
Hello,
Thanks for the response! I was not able to find anything about how to enable the RAMCFG clock, could you please provide more detail on that?
Additionally, is there any example code I could look at for generating RAMECC errors?
Thanks again,
Jared
2024-10-01 06:27 AM - edited 2024-10-01 06:28 AM
Hey. I tried your recommendation but still no luck. Please find the code used below.
I notice that when stepping through, writing to the sram shows no change in value. Could that be indicative of something wrong?
I have also assumed the HAL generated init functions are configuring the clock of the ramecc as you mentioned.
Thank you for your help!
main loop:
#define SRAM_3_START (uint32_t*)0x30040000
#define SRAM_3_END (uint32_t*)0x30047FFF
#define SRAM_2_START (uint32_t*)0x30020000
#define SRAM_2_END (uint32_t*)0x3003FFFF
#define SRAM_1_START (uint32_t*)0x30000000
#define SRAM_1_END (uint32_t*)0x3001FFFF
int main(void)
{
/* USER CODE BEGIN 1 */
CPU_CACHE_Enable();
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* Configure the system clock */
SystemClock_Config();
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_RAMECC_Init();
/* USER CODE BEGIN 2 */
volatile uint32_t* mem_pointer1 = (volatile uint32_t*)SRAM_1_START;
volatile uint32_t* mem_pointer2 = (volatile uint32_t*)SRAM_2_START;
volatile uint32_t* mem_pointer3 = (volatile uint32_t*)SRAM_3_START;
/* Execute a mass erase */
memset(SRAM_1_START, 0, sizeof(uint8_t)*0x7FFF); // 32 kb
memset(SRAM_2_START, 0, sizeof(uint8_t)*0x1FFFF); // 128 kb
memset(SRAM_3_START, 0, sizeof(uint8_t)*0x1FFFF); // 128 kb
/* Start RAM ECC */
START_RAMECC(&hramecc2_m1);
START_RAMECC(&hramecc2_m2);
START_RAMECC(&hramecc2_m3);
START_RAMECC(&hramecc2_m4);
START_RAMECC(&hramecc2_m5);
/* Write to memory location */
*mem_pointer1 = (uint32_t)0x12345678;
*mem_pointer2 = (uint32_t)0x12345678;
*mem_pointer3 = (uint32_t)0x12345678;
/* Stop RAM ECC */
STOP_RAMECC(&hramecc2_m1);
STOP_RAMECC(&hramecc2_m2);
STOP_RAMECC(&hramecc2_m3);
STOP_RAMECC(&hramecc2_m4);
STOP_RAMECC(&hramecc2_m5);
/* Modify 1 bit of data in memory location */
*mem_pointer1 ^= 0x00000001; // Flip one bit
*mem_pointer2 ^= 0x00010000;
*mem_pointer3 ^= 0x10000000;
/* Start ECC */
START_RAMECC(&hramecc2_m1);
START_RAMECC(&hramecc2_m2);
START_RAMECC(&hramecc2_m3);
START_RAMECC(&hramecc2_m4);
START_RAMECC(&hramecc2_m5);
/* Enable Interrupts */
ENABLE_RAMECC_INT(&hramecc2_m1);
ENABLE_RAMECC_INT(&hramecc2_m2);
ENABLE_RAMECC_INT(&hramecc2_m3);
ENABLE_RAMECC_INT(&hramecc2_m4);
ENABLE_RAMECC_INT(&hramecc2_m5);
/* Read Data */
while(1){
CurrentData = *mem_pointer1;
mem_pointer1++;
if(mem_pointer1 >= (volatile uint32_t*)SRAM_1_END){
break;
}
}
while(1){
CurrentData = *mem_pointer2;
mem_pointer2++;
if(mem_pointer2 >= (volatile uint32_t*)SRAM_2_END){
break;
}
}
while(1){
CurrentData = *mem_pointer3;
mem_pointer3++;
if(mem_pointer3 >= (volatile uint32_t*)SRAM_3_END){
break;
}
}
while(1);
}
CubeMX init function:
static void MX_RAMECC_Init(void)
{
/* USER CODE BEGIN RAMECC_Init 0 */
/* USER CODE END RAMECC_Init 0 */
/* USER CODE BEGIN RAMECC_Init 1 */
/* USER CODE END RAMECC_Init 1 */
/** Initialize RAMECC2 M1 : SRAM1_0
*/
hramecc2_m1.Instance = RAMECC2_Monitor1;
if (HAL_RAMECC_Init(&hramecc2_m1) != HAL_OK)
{
Error_Handler();
}
/** Initialize RAMECC2 M2 SRAM1_1
*/
hramecc2_m2.Instance = RAMECC2_Monitor2;
if (HAL_RAMECC_Init(&hramecc2_m2) != HAL_OK)
{
Error_Handler();
}
/** Initialize RAMECC2 M3 : SRAM2_0
*/
hramecc2_m3.Instance = RAMECC2_Monitor3;
if (HAL_RAMECC_Init(&hramecc2_m3) != HAL_OK)
{
Error_Handler();
}
/** Initialize RAMECC2 M4 : SRAM2_1
*/
hramecc2_m4.Instance = RAMECC2_Monitor4;
if (HAL_RAMECC_Init(&hramecc2_m4) != HAL_OK)
{
Error_Handler();
}
/** Initialize RAMECC2 M5 : SRAM3
*/
hramecc2_m5.Instance = RAMECC2_Monitor5;
if (HAL_RAMECC_Init(&hramecc2_m5) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN RAMECC_Init 2 */
/* NVIC configuration for RAMECC interrupt */
/* Priority: high-priority */
HAL_NVIC_SetPriority(ECC_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(ECC_IRQn);
/* USER CODE END RAMECC_Init 2 */
}
Helper functions:
void ENABLE_RAMECC_INT(RAMECC_HandleTypeDef* hramecc){
/* Enable monitor notifications */
/* ECC single error notification and ECC double error notification */
if (HAL_RAMECC_EnableNotification(hramecc, (RAMECC_IT_MONITOR_SINGLEERR_R | RAMECC_IT_MONITOR_DOUBLEERR_R))!= HAL_OK)
{
Error_Handler();
}
}
void START_RAMECC(RAMECC_HandleTypeDef* hramecc){
/* Start Monitor : Enable latching failing information
Failing information : * Failing address
* Failing Data Low
* Failing Data High
* Hamming bits injected
*/
if (HAL_RAMECC_StartMonitor(hramecc) != HAL_OK)
{
Error_Handler();
}
}
void STOP_RAMECC(RAMECC_HandleTypeDef* hramecc){
if (HAL_RAMECC_StopMonitor(hramecc) != HAL_OK)
{
Error_Handler();
}
}
Callback Functions:
void HAL_RAMECC_DetectErrorCallback(RAMECC_HandleTypeDef *hramecc)
{
if ((HAL_RAMECC_GetRAMECCError(hramecc) & HAL_RAMECC_SINGLEERROR_DETECTED) != 0U)
{
RAMECCSingleErrorDetected ++;
}
if ((HAL_RAMECC_GetRAMECCError(hramecc) & HAL_RAMECC_DOUBLEERROR_DETECTED) != 0U)
{
RAMECCDoubleErrorDetected ++;
}
hramecc->RAMECCErrorCode = HAL_RAMECC_NO_ERROR;
HAL_GPIO_WritePin(GPIOJ, GPIO_PIN_2, GPIO_PIN_RESET);
}
void ECC_ErrorCallback(RAMECC_HandleTypeDef *hramecc)
{
HAL_GPIO_WritePin(GPIOJ, GPIO_PIN_2, GPIO_PIN_RESET);
// Handle the ECC error
while(1);
}
2024-10-01 07:17 AM
Hello @snmunters ,
See this thread.
2024-10-01 07:38 AM
Hello @SofLit,
I authored the post you linked, is that really the recommended way of triggering a ram ecc error? I made the post because it was literally the only way I was able to figure out how to inject an error. Any feedback would be appreciated.
-Jared
2024-10-01 07:46 AM
Hi Sof,
That post is completely different from the steps you recommended.
As far as I understand, @20jmorrison seems to be reading uninitialized memory
I'm a little confused now?
Thanks!
2024-10-01 08:02 AM
To emulate an ECC error you need to read from an initialized memory.