STM32: Reduce HAL_deepsleep stack usage

There are cases where a call hal_deepsleep would overflow the idle task
stack, especially in developper or debug profile.

In order to avoid this case, we split ForceClockOutofDeepSleep
into two separate functions the two structure RCC_ClkInitStruct and
RCC_OscInitStruct are not allocated at the same time.
pull/7241/head
Laurent MEUNIER 2018-06-18 16:35:42 +02:00
parent ed9a1f1327
commit 81adafb5a7
1 changed files with 47 additions and 35 deletions

View File

@ -49,38 +49,16 @@ static void wait_loop(uint32_t timeout)
return;
}
// On L4 platforms we've seen unstable PLL CLK configuraiton
// when DEEP SLEEP exits just few µs after being entered
// So we need to force MSI usage before setting clocks again
static void ForceClockOutofDeepSleep(void)
static void ForcePeriphOutofDeepSleep(void)
{
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
uint32_t pFLatency = 0;
/* Enable Power Control clock */
__HAL_RCC_PWR_CLK_ENABLE();
#ifdef PWR_FLAG_VOS
/* Poll VOSF bit of in PWR_CSR. Wait until it is reset to 0 */
//while (__HAL_PWR_GET_FLAG(PWR_FLAG_VOS) != RESET) {};
#endif
/* Get the Oscillators configuration according to the internal RCC registers */
HAL_RCC_GetOscConfig(&RCC_OscInitStruct);
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
#if (TARGET_STM32L4 || TARGET_STM32L1) /* MSI used for L4 */
/**Initializes the CPU, AHB and APB busses clocks
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_MSI;
RCC_OscInitStruct.MSIState = RCC_MSI_ON;
RCC_OscInitStruct.MSICalibrationValue = RCC_MSICALIBRATION_DEFAULT;
RCC_OscInitStruct.MSIClockRange = RCC_MSIRANGE_4; // Intermediate freq, 1MHz range
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) {
error("clock issue\r\n");
}
/* Get the Clocks configuration according to the internal RCC registers */
HAL_RCC_GetClockConfig(&RCC_ClkInitStruct, &pFLatency);
@ -100,16 +78,6 @@ static void ForceClockOutofDeepSleep(void)
error("clock issue\r\n");
}
#else /* HSI used on others */
/**Initializes the CPU, AHB and APB busses clocks
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.HSICalibrationValue = 16;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) {
error("clock issue");
}
/* Get the Clocks configuration according to the internal RCC registers */
HAL_RCC_GetClockConfig(&RCC_ClkInitStruct, &pFLatency);
@ -132,6 +100,50 @@ static void ForceClockOutofDeepSleep(void)
#endif // TARGET_STM32L4
}
static void ForceOscOutofDeepSleep(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
/* Enable Power Control clock */
__HAL_RCC_PWR_CLK_ENABLE();
/* Get the Oscillators configuration according to the internal RCC registers */
HAL_RCC_GetOscConfig(&RCC_OscInitStruct);
#if (TARGET_STM32L4 || TARGET_STM32L1) /* MSI used for L4 */
/**Initializes the CPU, AHB and APB busses clocks
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_MSI;
RCC_OscInitStruct.MSIState = RCC_MSI_ON;
RCC_OscInitStruct.MSICalibrationValue = RCC_MSICALIBRATION_DEFAULT;
RCC_OscInitStruct.MSIClockRange = RCC_MSIRANGE_4; // Intermediate freq, 1MHz range
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) {
error("clock issue\r\n");
}
#else /* HSI used on others */
/**Initializes the CPU, AHB and APB busses clocks
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.HSICalibrationValue = 16;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) {
error("clock issue");
}
#endif // TARGET_STM32L4
}
/* The content of this function has been split into 2 separate functions
so that the involved structures are not allocated on the stack in parallel.
This will reduce the maximum stack usage in case on non-optimized / debug
compilers settings */
static void ForceClockOutofDeepSleep(void)
{
ForceOscOutofDeepSleep();
ForcePeriphOutofDeepSleep();
}
void hal_sleep(void)
{
// Disable IRQs