FreeRTOS and deep sleep mode

Hi,

Is it possible to combine the freertos_ble_peripherial_server_bond and the sleep_RAM_retention examples?
I would like to have an application like the freertos_ble_peripherial_server_bond, but as soon as a specific SPI message arrives, it goes into deep sleep by using the Sys_PowerModes_Sleep_WakeupFromFlash() function. The wake-up should happend via the dedicated wake-up pad and therefore restart the application.

The question is: Is the usage of the Sys_PowerModes_Sleep_WakeupFromFlash() function even possible while using FreeRTOS?
(My initial try was not successful, that’s the reason I’m asking)

Thanks for the help

Hi @stzi ,
After having look at the freeRTOS sample code, I think you might not be able to use deep sleep ( call Sys_PowerModes_Sleep_WakeupFromFlash() function) with FreeRTOS.
The reason is FreeRTOS uses Kernel and scheduler etc. Deep sleep mode could not use kernel.

Hi @larry.zhu,

Thank you for your response. I tried to find a different approach: I will stop the RTOS and then go to sleep.
My understanding is:
The RTOS scheduler is started within osKernelStart() with vTaskStartScheduler().
According to the FreeRTOS documentation, if you call vTaskEndScheduler() it will resume the code after the point where vTaskStartScheduler() was called.
So if my main is structured like this:
int main(void){

     /* some code before this point... */
     vTaskStartScheduler();

     /* code will continue here, after calling vTaskEndScheduler() */
     Sleep_Mode_Config(&sleep_mode_flash_env);
     Sys_PowerModes_Sleep_WakeupFromFlash(&sleep_mode_flash_env);

If I now call vTaskEndScheduler() within a Thread while the RTOS is running, it will stop the RTOS and resume the code at the above mentioned position, is that correct?
I tried that and it is not working. Is the vTaskEndScheduler() not implemented correctly or am I missing something?

Regards

Hi @stzi ,
In this sleep mode, only ACS registers can be saved. all others will be reset.
So I think you might need do RTOS reset/initialization after wakeup.

Yes I know. But this is not a problem. I just need the sleep to work. I will restart the RTOS.
Should it work this way?
It does not work on my side. After calling vTaskEndScheduler() it does not continue at the mentioned position, after vTaskStartScheduler(), why?

Regards

Hi @stzi ,
I might not fully understand your question.

  1. You want to verify if vTaskEndScheduler() work properly without sleep, is that right?
  2. Or you want to verify if vTaskEndScheduler() can work with sleep , is that right?

As mentioned above:

  1. I want to stop the FreeRTOS with vTaskEndScheduler()
  2. Then start deep sleep mode

But vTaskEndScheduler() does not work as described in the documentation.
How is it supposed to work on the RSL10?

Hi @stzi ,

  1. You want to ask Freertos question for vTaskEndScheduler().
    You can reference this link:
    FreeRTOS: how to End and Restart the Scheduler | MCU on Eclipse

I think you don’t understand my question correctly.
I want to know, what the RSL10 does after I call vTaskEndScheduler()??
ACCORDING to the FreeRTOS documentation, it should continue after vTaskStartScheduler(), is that the case for the RSL10 as well?

Again, I want to know the behaivior of the RSL10 after calling vTaskEndScheduler().
Is this funciont properly implemented and can I use it the way it is described above??

Hi @stzi ,
After success to apply vTaskEndScheduler(), the Freertos will be reset and stop scheduler.
To answer your question if it will impact RSL10, yes, it will impact BLE and there is no BLE advertising (For example).

Your question:
I want to know the behaivior of the RSL10 after calling vTaskEndScheduler().
Answer: Yes. It will impact RSL10 BLE activity.
Yes. you can continue after using vTaskStartScheduler(), but you might need reset BLE as well since you don’t save all BLE state information before you stop Freertos.

Thank you. I implemented it, but it is not behaving as it should. Therefore some follow-up questions:

  1. If I call vTaskEndScheduler(), where does the firmware resume running?
    (Because it will shut down the schueduler, it can not continue to run within a task)

  2. It should continue after vTaskStartScheduler(), is this correct?

(Please take a look at my second post)
Regards

Hi @stzi ,
Question1 : If I call vTaskEndScheduler(), where does the firmware resume running?
(Because it will shut down the schueduler, it can not continue to run within a task)
Answer: I don’t know. it depends on where you call vTaskEndScheduler(),
if you don’t save states and related information, you can’t resume your task.

Question 2: It should continue after vTaskStartScheduler(), is this correct?
Answer: I have no experience for using vTaskEndScheduler(). but based on the the link, it is correct.
If you use Freertos thread for BLE stack, it can’t continue with BLE.
FreeRTOS: how to End and Restart the Scheduler | MCU on Eclipse

Thank you @larry.zhu ,

I call vTaskEndScheduler() within a task. I don’t save any state, because it is not necessary for my project.
I agree, based on the informations from the FreeRTOS documentation, it should continue after the vTaskStartScheduler(). This is also the reason why I posted my question here. I tested it and does not work!
I assume there is a problem with the implementation on the RSL10.
I posted the method I am using above, is this the proper way or am I missing something?
Anyone who can help me?

Thanks.

Hi @stzi,

You are correct that the 'vTaskEndScheduler() ’ function on RSL10 does not return to ‘main()’ as the freeRTOS document seems to suggest, but this was not decided by onsemi as we use the standard ARM M-series freeRTOS implementation as provided.

Based on the function comments below (provided by ARM), you can see that the port functionality required to end the scheduler was not addded due to being ‘Not implemented in ports where there is nothing to return to’.

image

If you would like to use Deep Sleep + freeRTOS on RSL10, you have 2 main options to consider:

  1. Implementing custom context saving and switching as outlined in the article shared by @larry.zhu
  2. Configuring and entering Deep Sleep within one of your tasks

Hi @brandon.shannon

Thank you very much.
About your 2. suggestion:
I thought it is not possible to use the deep sleep within a task while the RTOS is running. What do you mean with your suggestion?

@stzi

So far we don’t have sample for reference in this case. You can share your project if you find something wrong.
I think RSL10 can enter into sleep within a task.

a. For sure we cannot force the freeRTOS to end before entering the Deep Sleep, so it will have to be smart about the task coordination if it has critical tasks that code cannot sleep during (ie. using global flags or semaphores).

b. Sys_PowerModes_Sleep_WakeupFromFlash — > ACS->PWR_MODES_CTRL= PWR_SLEEP_MODE;
The BLE stack will check if current events are finished or not, it will start sleep when current events finished.
For example, RSL10 only can start real sleep after advertising event finished while advertising.