STM32H747: CM4 stalls when CM7 (D1 Domain) enters DStop mode (Tickless Idle)
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.
- If I switch to HAL_PWREx_EnterSTOPMode(PWR_MAINREGULATOR_ON, PWR_STOPENTRY_WFI, PWR_D1_DOMAIN), the CM4 core seems to "die" or freeze as soon as CM7 enters the DStop state.
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);
