how to update time after sleep mode

zub wrote on Saturday, January 05, 2019:

Hello,

I am looking for way how to update time - value of xTickCount
after MCU is woken from deep sleep.

I do not use tickless idle mode as I don’t want scheduler to
call sleep mode but it is called by program.

In my case I have many tasks and software timers running, and
once I detect that supply voltage is low, I modify periphery and externall
devices to low current consumption and disable interrupts and go to
deep sleep - waiting for wakeup from low power timer - after 5 seconds.

Till here my program works fine, however now I need to modify FreeRTOS time -
xTickCount but I dont know how to do it.

Is this scenario correct?

If yes, how to modify time?

Thanks

Radomir

heinbali01 wrote on Sunday, January 06, 2019:

Is this what you are looking for?

zub wrote on Sunday, January 06, 2019:

hi, thanks for response

yes, I have tested vTaskStepTick function … however this function is conditionally compiled
with #if ( configUSE_TICKLESS_IDLE != 0 )
but I don’t want to use tickless idle as I don’t want to go to sleep in the idle.

I also tried to make a copy of function and I call it after wakeup, however program hanged.

Not sure what pre requisitions there are to have it running…

Radomir

richarddamon wrote on Sunday, January 06, 2019:

My first thoughts is that you actually ARE using a form of tickless idle, so the simplest thing might be to enable the functionality with configUSE_TICKLESS_IDLE, but then there is a test call back macro in the implementation that is designed to asked if it is a good time to actually activate it, and you use that to just always say NO!

A second question would be, do you really need to update the tick count here, are there any time outs that happen over this period that need to be updated?

zub wrote on Sunday, January 06, 2019:

thank you for response!
regarding tickless with callback function - yes, this may be possible, however I wanted to avoid this besause I have many tasks and working threads running (sw. timers) and I am afraid that time to sleep will not be deterministic … also I have simplified example above and there are many conditions to go to sleep … coding this way would be really mess… thats why tickless idle is not suitable for me

second question - keeping tick count - I use it as kind of “realtime clock” and I use it in other tasks to keep periodic heartbeat for communication. And if I sleep, “RTC” has a far big error, causing loss of connection …

question is if changing tick count is even possible - if not I’ll need change whole concept

richarddamon wrote on Sunday, January 06, 2019:

My comment on the callback is that I beleive the tickless implementations have a callback that is called BEFORE actually entering tickless idle mode to allow the system to say it isn’t a good time to go tickless idle. The system first checks the shortest timeout present, and if that is too short, it won’t go into tickless idle (so if you set this number high enough, if you have a task always running on periodic activation, it will never go tickless). If the first check passes, there is a second call to allow the application to say it knows of some other reason to not go tickless (perhaps there is I/O in progress that going tickless would interfear with).

Updating the current tick sould definately be posible, as that is what tickless mode does, but it may be necessary to have ticlkless mode enabled (even if never used) to do so.

zub wrote on Sunday, January 06, 2019:

I have also tried to call it in save mode
__disable_irq();
vTaskSuspendAll ();
vTaskStepTick( 1000 ); // spatna implementace, nefunguje
xTaskResumeAll ();
__enable_irq();

    but hangs as well ...
    
    Radomir

richarddamon wrote on Sunday, January 06, 2019:

Onething that came to mind, is that the vTaskStepTick was written based on the assumption of Tickless Idle, so it might have an assumption that no timeout expire with the call, and if that isn’t true there might be an issue.

One question, you say the program hangs, can you stop the system with a debugger and find out what it is doing?

rtel wrote on Sunday, January 06, 2019:

Not read this whole thread - but can confirm that vTaskStepTick()
assumes no deadlines are missed - or putting it another way - that the
system will leave sleep mode when the next timeout expires at the very
latest.

heinbali01 wrote on Monday, January 07, 2019:

I think it is still not clear to the team what you want to accomplish.

You wrote:

I am looking for way how to update time after MCU is woken from deep sleep.

And you also wrote:

but I don’t want to use tickless idle as I don’t want to go to sleep in the idle.

That sounds contradictory. OR do you insist on going to sleep from a user task? And if so, for what reason would you want that?

I do not use tickless idle mode as I don’t want scheduler to call sleep mode but it is called by program.

Could there be a misunderstanding here? When you use tickless mode, the scheduler will never invoke a sleep mode. You are supposed to provide the code that brings your CPU into a (deep) sleep.
The scheduler will tell you when you must wake-up, because the scheduler knows when the first (internal) timer will expire. Another reason to wake-up, of course, can be a hardware interrupt that may not be ignored.

In tickless mode, you are to provide this function:

#if configUSE_TICKLESS_IDLE == 1
    void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime )
    {
        /* Sleep at most 'xExpectedIdleTime' ticks. */
        ulCompleteTickPeriods = vDeepSleep( xExpectedIdleTime );
        portENTER_CRITICAL();
        {
            vTaskStepTick( ulCompleteTickPeriods );
        }
        portEXIT_CRITICAL();
    }
#endif

In fact, it doesn’t matter what you do in this function, as long as it does not last too long ( too short is no problem ), and as long as you keep the tick-counter up-to-date.

If you do not want to sleep from the idle task, and in stead you want to sleep from an application task, can you explain what would be the advantage?

zub wrote on Monday, January 07, 2019:

Hello Hein,
you described it correctly … I dont want scheduler to decide when to wake up and
I insist on going to sleep from a user task :slight_smile: … at least - that was my original idea …
why?

Imagine I have some car application which is running several tasks and working threads (sw. timers). Application is monitoring several sensors, voltage , two CAN, internal states of car, and also keeping GPRS and Bluetooth connection.

Now there is also one task running complex statemachine and actually only if statemachine ends up in state - “go to sleep” I need to put MCU to sleep mode.

My idea was to clean up hw. to lower power consumption, prepare wakeup events and go deep sleep - leaving all tasks and sw. timers in states they actually are.

I have several wakeup sources (2x CAN, 1sec timer and GPRS packet). Wakeup sources determine, where statemachine will follow after wakeup.

Now … if I want to use tickless idle, I would have to block all tasks and stop sw. timers, then instruct some way vPortSuppressTicksAndSleep function to go to sleep, and after wake up pass wakeup source to statemachine. And this way seems to me quite complicated…

However … I am thinking about low power mode in freertos for first time … so maybe I am completly wrong … and I should redesign all tasks to have option to block them for sleep purposes and use tickless …

Radomir

heinbali01 wrote on Monday, January 07, 2019:

Hi Radomir, now it is clear to me.

( I see that you wrote a new message which is still in moderation )

I think that you gave the best answer in your last paragraph: use tickless idle as it was meant to be used.

FreeRTOS provides many ways to control the behaviour of your tasks. If you don’t want other tasks to use CPU time, just let them block on any API:

  • xTaskNotifyWait()
  • ulTaskNotifyTake()
  • xSemaphoreTake()
  • xQueueReceive()
  • vTaskDelay()
  • vTaskDelayUntil()
    etc

The behaviour of all these function is very clear and deterministic ( predictable ).

The following could be the ground structure of your tasks:

    void vMyTask( void *pvParameter )
    {
    SemaphoreHandle_t xSemaphore = xSemaphoreCreateBinary;
    const TickType_t uxWaitTime = pdMS_TO_TICKS( 1000 );

        configASSERT( xSemaphore != NULL );

        for( ;; )
        {
            /* Let this task sleep for 1 second, or
            until the semaphore is given to. */
            xSemaphoreTake( xSemaphore, uxWaitTime );
            /* Do the work. */
            vMyTaskWork();
        }
    }

Note that you can unblock a task from within an ISR to get immediate attention from that task:

  • xTaskNotifyFromISR()
  • xSemaphoreGiveFromISR()
  • xQueueSendFromISR()
    etc

And if the task that is running your status machine wants to control the other tasks, it can use any of these API’s:

  • xTaskNotify()
  • xSemaphoreGive()
  • xQueueSend()
    etc

Note that TickType_t xTicksToWait is in units of clock-ticks.
This variable has one value with a special meaning: portMAX_DELAY, which means wait indefinitely. In that case the API will never time-out and only return in case of success.