Disabling the FreeRTOS

hnj16 wrote on Thursday, March 08, 2018:

How do I stop the scheduler completely? I do not want to halt and then resume. I would like to stop the kernal tick and start all over again by calling the scheduler from scratch. I found vTaskEndScheduler() https://www.freertos.org/a00133.html to be relevant to what I am looking for but I am wondering how to write an exit function in vPortEndScheduler () specific to my MCU that helps me stop the kernal tick. Any inputs is much appreciated.

Thanks,
Harsha

rtel wrote on Thursday, March 08, 2018:

vTaskEndScheduler() is not implemented for most platforms as those
platforms don’t have anything to return to. You could use setjmp() to
provide a jump point back to a pre-scheduler point, but would have to
disable the interrupts used by FreeRTOS first. It also depends which
platform you are using - on Cortex-M ports for example the stack used by
main() is re-used as a system stack, so all bets are off if you expect
to find anything useful in that stack if you jmp() to it. Perhaps
describe what you want to achieve, rather than describe an
implementation you are wanting to be available - as your post is framed
at the moment it sounds like you just want to perform a device reset as
opposed to a software reset (which could be achieved in a number of ways
depending on the platform).

hnj16 wrote on Friday, March 09, 2018:

Hi Richard,

Thank you for your response. I am using STM32L053. It is Cortex M0+ processor. I am trying to save power by disabling the freertos when the device goes to sleep. The system will be in idle mode most of the duration. I would like to stop the RTOS completely instead of halting and then resume on wakeup. So ideally, I do not want tickless mode as it would consume power by running the clock at lower rate. So, I would like to

  1. Stop the scheduler (i.e. Delete all tasks and disable the kernal tick)
  2. Go to Standby mode
    3)Restart the scheduler upon wakeup (External GPIO signal)

How do I find out if vTaskEndScheduler() works for my platform? If it does not support, would it be a right approch to signal each task to delete itself?

Thanks for your time, I appreciate it.

–Harsha

rtel wrote on Friday, March 09, 2018:

How do I find out if vTaskEndScheduler()

You have the source code, so look at its implementation. It calls
vPortEndScheduler(), which [in the GCC CM0 port] is implemented as:

void vPortEndScheduler( void )
{
     /* Not implemented in ports where there is nothing to return to.
     Artificially force an assert. */
     configASSERT( uxCriticalNesting == 1000UL );
}

I think you could still use the tickless mode, just don’t have a clock
running, so the tickless mode will never wake the system up, only the
external GPIO.

Alternatively, it seems all you want to do is completely restart the
device when the GPIO interrupt executes, so why not just disable the
tick interrupt before sleeping, then have the GPIO interrupt reset the
the MCU when it brings the system out of sleep (or just have it jump to
the reset vector/function so the C start up code runs again)? That
would seem to be a simple solution.

You could do something more complex, like keep a registry of all the
task handles in the system and manually delete them before sleeping.

hnj16 wrote on Friday, March 09, 2018:

void vPortEndScheduler( void )
{
/* Not implemented in ports where there is nothing to return to.
Artificially force an assert. */
configASSERT( uxCriticalNesting == 1000UL );
}

The control gets to this function and sits here forever, should I add any code here for it to exit the task and return to the main function, where vTaskScheduler() was called?

“I think you could still use the tickless mode, just don’t have a clock
running, so the tickless mode will never wake the system up, only the
external GPIO.”
So upon wake up, the RTOS tick count value has to be changed when the tick interrupt is restarted. How do I achieve this without having another clock running?

Yes, you are right. Restarting on GPIO interrupt would be a simple approach.