cancel
Showing results for 
Search instead for 
Did you mean: 

STM32H750 RAMECC Testing

snmunters
Associate II

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. 

snmunters_0-1720621950335.png

Any idea what Im missing? Thanks!

 

8 REPLIES 8
20jmorrison
Associate II

I am having the same issue. Were you ever able to figure this out?

Hello @snmunters and  @20jmorrison 

To generate a RAM ECC error, please follow these steps:

  1. Enable the RAMCFG clock and initialize the handle.
  2. Execute a mass erase.
  3. Start ECC.
  4. Write 32 bits of data.
  5. Stop ECC.
  6. Modify one bit within the previously written 32 bits of data.
  7. Start ECC and enable IT.
  8. Perform a data read.

If your question is answered, please close this topic by clicking "Accept as Solution".

Thanks
Omar

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

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);
}

 

 



Hello @snmunters ,

See this thread.

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.

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

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!

To emulate an ECC error you need to read from an initialized memory.

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.