2026-04-11 12:16 PM - last edited on 2026-04-11 12:26 PM by mƎALLEm
Hi everyone,
I am working on a dual-core project using the STM32H747XI. I am implementing a custom Tickless Idle mode in FreeRTOS on the Cortex-M7 (CM7) core using LPTIM1 as the wakeup source.
I’m facing a specific issue regarding the interaction between D1 and D2 domains:
The Scenario:
CM4 is running a continuous task (intended to stay active).
CM7 enters low-power mode via vPortSuppressTicksAndSleep.
If I use HAL_PWR_EnterSLEEPMode(), everything works perfectly—CM4 keeps running, and CM7 wakes up as expected.
Is it physically possible for CM4 to continue executing code if the D1 domain is in DStop (CM4 is using only LPTIM1 on D3 and timers on D2)?
Code snippet used on CM7:
_weak void vPortSuppressTicksAndSleep(TickType_t xExpectedIdleTime) {
// Generated when configUSE_TICKLESS_IDLE == 2.
// Function called in tasks.c (in portTASK_FUNCTION).
// TO BE COMPLETED or TO BE REPLACED by a user one, overriding that weak one.
uint32_t ulReloadValue, ulCompleteTickPeriods;
TickType_t xModifiableIdleTime;
if (xExpectedIdleTime > 0xFFFF) {
xModifiableIdleTime = 0xFFFF;
} else {
xModifiableIdleTime = xExpectedIdleTime;
}
// HAL_GPIO_WritePin(LED_1_GPIO_Port, LED_1_Pin, GPIO_PIN_SET);
HAL_SuspendTick();
HAL_TIM_Base_Stop_IT(&htim13);
__disable_irq();
if (eTaskConfirmSleepModeStatus() == eAbortSleep) {
__enable_irq();
HAL_ResumeTick();
} else {
ulReloadValue = xModifiableIdleTime - 1;
if (HAL_LPTIM_TimeOut_Start_IT(&hlptim1, 0xFFFF, ulReloadValue)
!= HAL_OK) {
__enable_irq();
HAL_ResumeTick();
return;
}
(void) SysTick->CTRL;
SCB->ICSR |= SCB_ICSR_PENDSTCLR_Msk; //oznacza zapis 1 do tego bitu.
__DSB();
__ISB();
HAL_PWREx_EnterSTOPMode(PWR_MAINREGULATOR_ON, PWR_STOPENTRY_WFI, PWR_D1_DOMAIN);
uint32_t ulCountValue = HAL_LPTIM_ReadCounter(&hlptim1);
HAL_LPTIM_TimeOut_Stop_IT(&hlptim1);
if (ulCountValue > xModifiableIdleTime) {
ulCompleteTickPeriods = xModifiableIdleTime;
} else {
ulCompleteTickPeriods = ulCountValue;
}
ulHighFrequencyTimerTicks += (ulCompleteTickPeriods * 1000UL);
vTaskStepTick(ulCompleteTickPeriods);
__enable_irq();
HAL_ResumeTick();
HAL_TIM_Base_Start_IT(&htim13);
2026-04-11 12:43 PM
> Is it physically possible for CM4 to continue executing code if the D1 domain is in DStop
Yes, it's physically possible as long as CPU2 doesn't use anything in the D1 domain.
I suggest creating a new project where you only look at this aspect and try getting that to run. It's possible your application is using something else that you're missing.
2026-04-12 1:35 AM
Thanks for the insight. I have a follow-up question regarding the memory architecture:
My CPU2 (CM4) is currently executing code directly from Flash memory (mapped at 0x08100000), while its stack and data are in D2-domain RAM (0x10000000).
Since the Flash memory controller is physically located within the D1 domain, does entering DStop on D1 effectively cut off the Flash clock or power for the entire system?
If so, does this mean that CPU2 (running in D2) is physically blocked from fetching instructions the moment D1 enters DStop, even if the D2 domain itself remains in DRun? I suspect this 'hidden' dependency on the D1 bus matrix is what's causing my CM4 to stall, as it works fine in Sleep mode (where the D1 bus remains active).
2026-04-12 3:11 AM
I’ve also observed that if D1 is in RUN/SLEEP mode, then D2 does not properly enter or operate in STOP mode.
2026-04-12 3:11 AM
I’ve also observed that if D1 is in RUN/SLEEP mode, then D2 does not properly enter or operate in STOP mode.
2026-04-12 6:36 AM
It looks like the issue is related to LPTIM2 being located in the D3 domain.
In my setup:
2026-04-13 2:29 AM
Hello @Patryk_Kucia
According to the RM table 59, D3 peripherals can remain clocked in STOP mode if autonomous mode is enabled (LPTIM2AMEN = 1) and its kernel clock source is a low-power clock that remains active in D3Stop, i.e. LSE or LSI.
If LPTIM2 is clocked from PCLK/PLL or AMEN is not set, it will not run in STOP.