2018-05-02 05:30 AM
Hi all,
I am using the STM32L151RCTxA MCU with STM32CUBEMX.
I have configured FREERTOS, a UART using DMA and tickless IDLE.
I am attempting to run my MCU in low power mode.
My first misunderstanding is how to get the MCU to trigger the PreSleepProcessing and PostSleepProcessing functions. Should it not be a case of simply suspending all my tasks with osThreadSuspendAll()?
If I bypass these functions and manually call the sleep functions I am successful calling HAL_PWR_EnterSLEEPMode(PWR_LOWPOWERREGULATOR_ON, PWR_SLEEPENTRY_WFI);
I would like to go one step further and go into STOP RTC mode. I have configured an RTC to wake up every 10s.
I am sending a command to a LoRa module to tell it to go to sleep. I am expecting an 'OK' response when it times out so that I can do some processing. If I call HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI); when I wake up via the RTC I seem to have lost my connection to the module and have to reset it to communicate on it again. I have read that I must deinit the UART and renitialise again on wakeup but that does not seem to help.
Has anybody experienced similar and found a way around it? My code to enter STOP mode is below.
HAL_RTCEx_DeactivateWakeUpTimer(&hrtc);
HAL_RTCEx_SetWakeUpTimer_IT(&hrtc, 0x5F46, RTC_WAKEUPCLOCK_RTCCLK_DIV16);HAL_UART_MspDeInit(&huart3); //if (HAL_UART_DeInit(&huart3) != HAL_OK) //{ // _Error_Handler(__FILE__, __LINE__); //} HAL_SuspendTick(); /* Enter Stop Mode */ //HAL_PWR_EnterSTOPMode(PWR_MAINREGULATOR_ON, PWR_STOPENTRY_WFI); HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI); HAL_ResumeTick(); /* Configures system clock after wake-up from STOP: enable HSI, PLL and select PLL as system clock source (HSI and PLL are disabled automatically in STOP mode) */ SystemClockConfig_STOP();On wakeup I simply initialise the UART and wait for the OK.
/* Disable Wakeup Counter */ HAL_RTCEx_DeactivateWakeUpTimer(&hrtc); HAL_UART_MspInit(&huart3); //MX_USART3_UART_Init(); //if (HAL_UART_Init(&huart3) != HAL_OK) //{ // _Error_Handler(__FILE__, __LINE__); //}I would really appreciate any help here. I feel I am close but there is some final thing I am not understanding
2018-06-18 06:45 AM
Hello,
Let me answer to your first question concerning tickles mode.
Once it is enabled within FreeRTOS_Config.h file it will be enabled automatically as soon as the only READY task will be IDLE one. In case you execute osThreadSuspendAll() you are suspending scheduler by suspending all tasks (including IDLE), so it is not the best entrance method.
Best Regards,
Artur
2018-06-18 10:44 AM
You don't care about the FreeRTOS timings? You don't seem to keep time in any way, nor report the time spent in tickless idle to FreeRTOS. The tickless idle is actually part of IDLE. It's called from the IDLE if the conditions are met.
IDLE is not executed if there is anything of higher priority to execute.
The tickless idle is a hook for a function that does the tickless idling - usually sleeping. It gets the time from 'now' to the moment the next task is due as a parameter. That's the maximum time you can spend in tickless idle, and at the return, you need to report to the system the actual time you spent in tickless idle, Otherwise you'll trash the FreeRTOS timings.
Also note that playing with the clocks can take several milliseconds.
The idea is that the system sleeps when it doesn't have anything worth while to do. Just let your tasks do their jobs and put them to sleep until the next round.
The tickless idle is less automatic than it first looks.
2018-06-21 06:22 AM
Hi Artur,
Thanks for your response...
I have been able to trigger SLEEP... There was a timer service started that I was not aware of... Suspending that enabled me to trigger PreSleepProcessing()...
2018-06-21 06:28 AM
Hi Juha,
Your comment below is exactly what I am trying to do. I am not sure I understand what you mean by keeping track of the time spent in tickless idle and reporting that back to RTOS.
My main issue is that I am unable to connect with my USART peripheral post STOP mode. That will send me a message from another device that has it's own timing. I am also using the RTC wakeup event in between... That is why I am not overly concerned about the RTOS timing??
The idea is that the system sleeps when it doesn't have anything worth while to do. Just let your tasks do their jobs and put them to sleep until the next round.
2018-06-21 10:44 AM
Is the USART you are using an LPUART? I guess stop mode shuts down all non-low power peripherals.
2018-06-21 11:00 AM
Hmm, telling by the data sheet (Table 5. Working mode-dependent functionalities) the USART should stay sane even in STOP mode...
What kind of LoRa module do you have? Is it possible that it can't handle something that happens when the processor goes to stop/wakes up?
2018-06-21 11:03 AM
No... It's a normal USART...
I have been given conflicting info.... Some tell me that it is possible with a normal UART if I just start the clocks, some say I must also renitialise, some say it is not possible...
It is working in a bare metal code configuration... It does not work when running on freeRTOS.
2018-06-21 11:03 AM
Exactly...
2018-06-21 11:17 AM
I am not sure I understand what you mean by keeping track of the time spent in tickless idle and reporting that back to RTOS.
You have to write the tickless idle function - maybe by editing a template. That function should keep track of the time actually slept and at the end, report it to OS with vTaskStepTick().