cancel
Showing results for 
Search instead for 
Did you mean: 

Stop STM32 from rerunning code when repowered

JKing.8
Associate III

I am using an STM32H753I-EVAL2. I have the real-time clock(RTC) counting. I want it to be set to the current time. I am successfully able to do this inside of MX_RTC_Init() with:

RTC_TimeTypeDef sTime = {0};  
sTime.Hours = 0x11;
sTime.Minutes = 0x22;
sTime.Seconds = 0x33;
if (HAL_RTC_SetTime(&hrtc, &sTime, RTC_FORMAT_BCD) != HAL_OK) {
  Error_Handler();
}

I configured the H7 such that the RTC continues to count when the main power is disconnected, through VBAT. The issue is that STM reruns all of the code when it is repowered, causing the time to be reset to where it started. Is there any way to avoid it rerunning all code? Thanks

1 ACCEPTED SOLUTION

Accepted Solutions
LCE
Principal

Put a variable in "no-init" RAM or in flash / eeprom.

 /* define NoInitSection in linker script, or store variable in flash / eeprom  */
uint32_t u32RtcSet __attribute__((section(".NoInitSection"))); 
 
/* on start check variable */
if( 0xD0ACCE55 != u32RtcSet )
{
    RTC_init();
    u32RtcSet = 0xD0ACCE55;
}

View solution in original post

5 REPLIES 5
LCE
Principal

Put a variable in "no-init" RAM or in flash / eeprom.

 /* define NoInitSection in linker script, or store variable in flash / eeprom  */
uint32_t u32RtcSet __attribute__((section(".NoInitSection"))); 
 
/* on start check variable */
if( 0xD0ACCE55 != u32RtcSet )
{
    RTC_init();
    u32RtcSet = 0xD0ACCE55;
}

nice one

we dont need to firmware by ourselves, lets talk
JKing.8
Associate III

This worked for me! For anyone in the future who needs more help with "define NoInitSection in linker script, or store variable in flash / eeprom", https://stackoverflow.com/questions/71375281/cant-edit-integer-with-noinit-attribute-on-stm32l476-with-custom-linker-file is a good resource.

Thank you for the great answer. D0ACCE55 is clever:)

> D0ACCE55 is clever

That one was stolen mostly from ARM / ST, to activate ARM's cycle counter, you have to do this, see DWT->LAR = 0xC5ACCE55:

/* CPU cycle count activation for debugging */
#if DEBUG_CPU_TIMING
	CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
	DWT->LAR = 0xC5ACCE55;
	DWT->CYCCNT = 0;
	DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk;
	DWT->CTRL |= DWT_CTRL_PCSAMPLENA_Msk;
#endif	/* DEBUG_CPU_TIMING */

Variable in RAM, in whichever section, won't "survive" VDD off (while RTC is running from VBAT).

The simplest and also probably the best thing to do is to avoid repeated RTC start/setup by looking at RCC_BDCR.RTCEN or equivalent. If it's set, RTC is already set and running, so no need to set and adjust it again.

Some look at INITS flag in RTC, but it's not always the best idea. Others write a particular value into the backup registers, but that is not necessary and wastes that register.

JW