cancel
Showing results for 
Search instead for 
Did you mean: 

How can I read and write simultaneously on specific SRAM address STM32.

Magnet
Associate II

Hi,

In the cases below I try to read value of an SRAM address which is in TIM2_IRQHandler(), from main() function or user Program() function, but no result!

anyone who is experienced or has idea?

void Program();
 
void TIM2_IRQHandler()
{ 
if(__HAL_TIM_GET_ITSTATUS(&TIM2_HandleStruct, TIM_IT_UPDATE) !=RESET)
   __HAL_TIM_CLEAR_IT(&TIM2_HandleStruct, TIM_IT_UPDATE);
 
*(__IO uint32_t *) 0x20020000 = Write1++;
 
if(Write1 == 1000)	
Write1 = 0;	
}
 
int main()
{
HAL_Init();
SystemClock_Config();
...
...
...
...
...
Program();
 
if(*(__IO uint32_t *) 0x20020000 == 10) // Does not work!!!
{ 
HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_14);
}
 
for(;;)
{
if(*(__IO uint32_t *) 0x20020000 == 10) // Does not work!!!
{ 
HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_14);
}
}
 
}
 
void Program()
{
if(*(__IO uint32_t *) 0x20020000 == 10) // Does not work!!!
{
HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_14);
}
}
 

6 REPLIES 6

Well two of these are dependent on the value being 10 at the given instant of the test, and the one in the loop is likely to toggle VERY fast during the whole time the value is 10. If you want it to toggle once, perhaps code for that.

I'd perhaps prefer the form:

*((volatile uint32_t *) 0x20020000)

Still a bit hacky. Anyway LOOK at the code generated by the compiler, and walk that as a sanity check on what exactly the micro is expected to do.

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..

Hi CliveTo.Zero,

my purpose is not toggle actually, but read the address value. I've tried to use 'volatile' that you suggest and then i observed it on debugger, but no value is read on the lines 25, 32 and 42 again. if you have more info and share would be glad.

What tool chain are you using?

What STM32, specifically, are you using?

Can you print the memory value?

What does the assembler code look like, it dictates what the micro will do?

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..

Tool chain MDK UVision KEIL V 5.26.2.0 - Mcu Stm32F767

The program writes the values from 0 to 1000 to the memory address 0x20020000 , but doesnt read from memory!

If only one of the cases below works (e.g. Case 3), that is enough.

Whole Code is:

#include<stdio.h>
#include<stdint.h>
#include<stdlib.h>
#include "stm32f7xx.h"                  // Device header
#include "stm32f7xx_hal.h"
 
/*-----SYSTEM OSCILLATOR & CLOCK CONFIGURATIONS-----*/
 
void SystemClock_Config(void)
	{
		RCC_OscInitTypeDef RCC_OscInitStruct;
		RCC_ClkInitTypeDef RCC_ClkInitStruct;
		
		
		__HAL_RCC_PWR_CLK_ENABLE();
		__HAL_RCC_RTC_ENABLE();
		__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
		
		HAL_StatusTypeDef  ret 						= HAL_OK;									//HAL_OK = 0x00
		RCC_OscInitStruct.OscillatorType 	= RCC_OSCILLATORTYPE_HSE; //Oscillator is HSE (High Speed External) - 8MHz on Nucleo Board
		RCC_OscInitStruct.HSEState 				= RCC_HSE_ON;							//HSE is ON
		RCC_OscInitStruct.HSIState				= RCC_HSI_OFF;						//HSI is OFF
		RCC_OscInitStruct.PLL.PLLState 		= RCC_PLL_ON;							//PLL (Phase Locked Loop) is ON
		RCC_OscInitStruct.PLL.PLLSource 	= RCC_PLLSOURCE_HSE;			//PLL Source is HSE Oscillator
		RCC_OscInitStruct.PLL.PLLM 				= 4;											//Main Division Factor for PLL VCO Input Clock : 2 - 63
		RCC_OscInitStruct.PLL.PLLN 				= 100;										//Main Multiplication Factor for PLL VCO Output Clock : 50 - 432
		RCC_OscInitStruct.PLL.PLLP 				= RCC_PLLP_DIV2;					//Main Division Factor for Main System Clock : 2,4,6,8
		RCC_OscInitStruct.PLL.PLLQ				= 9;											
		
		ret = HAL_RCC_OscConfig(&RCC_OscInitStruct);
		if(ret != HAL_OK)
		{
			while(1){;}
		}
		
		ret = HAL_PWREx_EnableOverDrive();
		if(ret != HAL_OK)
		{
			while(1){;}
		}
		
		RCC_ClkInitStruct.ClockType				= (RCC_CLOCKTYPE_SYSCLK | 
                RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);
		RCC_ClkInitStruct.SYSCLKSource		= RCC_SYSCLKSOURCE_PLLCLK;
		RCC_ClkInitStruct.AHBCLKDivider		= RCC_SYSCLK_DIV1;
		RCC_ClkInitStruct.APB1CLKDivider	= RCC_HCLK_DIV2;
		RCC_ClkInitStruct.APB2CLKDivider	= RCC_HCLK_DIV1;
		
		ret = HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_7);
		if(ret != HAL_OK)
		{
			while(1){;}
		}
	}
	
 
//----------TIMER FUNCTIONS----------//
 
TIM_HandleTypeDef TIM2_HandleStruct;
	
void Program();
 
void TIM2_IRQHandler()
	{
	if(__HAL_TIM_GET_ITSTATUS(&TIM2_HandleStruct, TIM_IT_UPDATE) !=RESET)
		 __HAL_TIM_CLEAR_IT(&TIM2_HandleStruct, TIM_IT_UPDATE);
	 {
		(*(__IO uint32_t *) 0x20020000) ++;
		
	
			if(*(uint32_t *) 0x20020000 == 1000)
			{
				HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_7);	
				(*(__IO uint32_t *) 0x20020000) = 0;
			}		
		}		
	}
 
//----------THE MAIN FUNCTION----------
 
int main()
{
	
	HAL_Init();
	SystemClock_Config();
	
	TIM_ClockConfigTypeDef	TIM_ClockConfigStruct;
	GPIO_InitTypeDef GPIO_InitStruct;
	
	__HAL_RCC_GPIOB_CLK_ENABLE();
	GPIO_InitStruct.Pin 	= GPIO_PIN_7 | GPIO_PIN_14;
        GPIO_InitStruct.Mode 	= GPIO_MODE_OUTPUT_PP;
        GPIO_InitStruct.Pull 	= GPIO_NOPULL;
        GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
	HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
	
	__HAL_RCC_TIM2_CLK_ENABLE();
	HAL_TIM_ConfigClockSource(&TIM2_HandleStruct, &TIM_ClockConfigStruct);
	TIM2_HandleStruct.Instance 								= TIM2;
	TIM2_HandleStruct.Init.Prescaler 					= 999;//Between 0x0000 - 0xFFFF
	TIM2_HandleStruct.Init.CounterMode 				= TIM_COUNTERMODE_UP;//UP: From 0 to Set Prescaler Value
	TIM2_HandleStruct.Init.Period 						= 99;//Between 0x0000 - 0xFFFF
	TIM2_HandleStruct.Init.ClockDivision 			= TIM_CLOCKDIVISION_DIV1;
	TIM2_HandleStruct.Init.RepetitionCounter 	= 0x00;
	TIM2_HandleStruct.Init.AutoReloadPreload 	= TIM_AUTORELOAD_PRELOAD_DISABLE;
	TIM2_HandleStruct.Channel	= TIM_CHANNEL_1;
	
	HAL_TIM_Base_Init(&TIM2_HandleStruct);
        HAL_TIM_Base_Start_IT(&TIM2_HandleStruct);
	
	HAL_NVIC_SetPriority(TIM2_IRQn, 0x00, 0x00);
	HAL_NVIC_EnableIRQ(TIM2_IRQn);
 
			
	Program();
	 
	if(*(__IO uint32_t *) 0x20020000 == 10) // Case 1 Does not work!!!
		{ 
			HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_14);
		}
 
	for(;;)
		{
			if(*(__IO uint32_t *) 0x20020000 == 10) // Case 2 Does not work!!!
			{ 
				HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_14);
			}
	}
 
	while(1)
		{}
 
}
/*--------------------USER PROGRAM--------------------*/
 
void Program()
{
	if(*(__IO uint32_t *) 0x20020000 == 10) // Case 3 Does not work!!!
	{
	HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_14);
	}
}

TDK
Guru

Well, case 3 only performs the comparison once, then it enters the while(1) loop, so that won't work.

case 1 also only does the comparison once

Case 2 should work. for(;;) is an odd way to do an infinite loop, but it should be valid, assuming nothing else is actually at that memory address.

Try this loop. Debug and step through the code and see if the value variable changes.

while (1) {
    uint32_t value = *(__IO uint32_t *) 0x20020000;
    if(value == 10) {
        HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_14);
    }
}

Also set a breakpoint in your interrupt to verify it's actually changing the value.

Accessing RAM by address is an odd thing to do. It's possible the compiler is using that address to store a variable unless you're treating it differently from other RAM addresses in your linker file.

If you feel a post has answered your question, please click "Accept as Solution".
Magnet
Associate II

Hi TDK,

Case 2 does also comparison once, but no more! 

Additionally, value of "value" doesnt appear during debug in watch list.

i wonder that, either reading and writing SRAM address simultaneously is possible or not?