Quality RTOS & Embedded Software

 Real time embedded FreeRTOS RSS feed 
Quick Start Supported MCUs PDF Books Trace Tools Ecosystem TCP & FAT




Loading

tickless mode timer problem - never sleeps

Posted by gmenhennitt on September 3, 2014

I'm using FreeRTOS 8.0.1 on an MSP430 F5335 (the IAR MSP430X port). I'm attempting to use tickless idle mode but am having a problem with FreeRTOS timers.

My application spends most of its time asleep. Every 15 seconds it wakes up, stays awake for about 200ms, and then goes back to sleep. During the wake period, I want to use a couple of timers.

So, I have three timers - one with a period of 15s and another two with shorter periods. The 15s timer runs always. The other two get started by the 15s timer callback. They get stopped by the callback of one of them once a particular condition is met.

What I see happen is that the system starts up correctly. It then correctly goes to sleep as FreeRTOS calls vPortSuppressTicksAndSleep() with a parameter corresponding to just less then 15s. I wake up, do my stuff, and then stop the two other timers. But I never get called to go back to sleep again.

I've spent a bit of time debugging this and it looks like there's some kind of race in the timer handling code. It looks like prvGetExpectedIdleTime() always return 1.

I'm sure that the other two timers are stopped. Also, the period of my other timers are greater than one tick, so I don't think that's the problem.

In the mean time, I've worked around it by setting the period of the two other times to > 15s. That seems to work but is pretty ugly. It also shows that my sleep/wake stuff is working correctly.

I'll spend more time coming up with a program that demonstrates it. But before I do, I'd like to check whether anybody else has seen this before.

Thanks, Graham


tickless mode timer problem - never sleeps

Posted by rtel on September 3, 2014

I've never noticed this behaviour, but have some questions.

What other tasks are in your system? Or more specifically, what is the priority of the timer service task relative to the other tasks in your system - have you tried with the timer service task being the highest priority task?

Looking at the prvGetExpectedIdleTime() function I see the only way it can return a non-zero value is if it goes through the else{} part, where the value returned is (xNextTaskUnblockTime - xTickCount), so your issue is related to the value of xNextTaskUnblockTime. That in turn is set by xNextTaskUnblockTime(), which in turn gets the next unblock time from the list of delayed tasks called - pxDelayedTaskList. Are you familiar enough with the FreeRTOS code to look in the pxDelayedTaskList structure using the debugger to see which task is at its head? That will tell you which task the kernel thinks needs to run again in 1 tick.

Regards.


tickless mode timer problem - never sleeps

Posted by gmenhennitt on September 3, 2014

Thanks for replying.

There are three tasks in the system (other than IDLE and TmrSvc). All have higher priorities than TmrSvc. But I've also tried with all priorities the same (including TmrSvc). I haven't tried TmrSvc having a higher priority.

But I don't think that's relevant. At the time when this happens, all my tasks are blocked on queues.

Yes, it's always xNextTaskUnblockTime equals xTickCount + 1. I haven't looked at the delayed task list yet. That was about as far as I got before I posted this forum topic.

I set a breakpoint in prvGetExpectedIdleTime() and see that it returns 1 as above. I then disable the breakpoint and run for a bit. When I re-enable the breakpoint, both xNextTaskUnblockTime and xTickCount have increased, but still xNextTaskUnblockTime equals xTickCount + 1.

I'll try looking at pxDelayedTaskList. I'm almost certain that it will be TmrSvc at the head.

Thanks again, Graham


tickless mode timer problem - never sleeps

Posted by gmenhennitt on September 3, 2014

Ok, a quick bit of debugging later...

At the breakpoint in prvGetExpectedIdleTime(): - xTickCount == 0x34d - xNextTaskUnblockTime == 0x34e - pxDelayedTaskList->uxNumberOfItems == 1 - pxDelayedTaskList->pxNext->xItemValue == 0x34e - ((TCB_t*)(pxDelayedTaskList->pxIndex->pxNext->pvOwner))->pcTaskName == "Tmr Svc"

I'm not sure what else you might need. I'll try to come up with a simple program that demonstrates the problem (but it might not be easy!).

Thanks, Graham


tickless mode timer problem - never sleeps

Posted by rtel on September 4, 2014

Yes, if you can come up with a simple example that would be very useful for determining why this is the case.

Regards.


tickless mode timer problem - never sleeps

Posted by gmenhennitt on September 10, 2014

After trying to come up with a demo program for a while, I investigated a bit further. I now know what my problem is and I have a partial solution for it. What I was trying to do was to start my timers from inside vPortSuppressTicksAndSleep() after it had woken. That seems not to work - I don't think that I can make FreeRTOS calls from inside that callback. So, I moved starting them to inside the 15s timer callback (yes, I know that's what I said I already did!). That bit now works correctly.

However, I have another, related, problem. I can also get woken by an external interrupt. I want to start the timers when this occurs. What will happen if I call xTimerStartFromISR() from my ISR while FreeRTOS is asleep in vPortSuppressTicksAndSleep()? What would be nice is if there was a callback from FreeRTOS to say that it had just been woken from sleep, where it was allowable to start the timers.

I'll do some more investigating.

Thanks, Graham


tickless mode timer problem - never sleeps

Posted by rtel on September 10, 2014

xTimerStartFromISR() from my ISR while FreeRTOS is asleep in vPortSuppressTicksAndSleep()?

I think that should be ok, but note the scheduler is suspended while inside the vPortSuppressTicksAndSleep() function (to prevent race conditions while the time is adjusted) so the call will not have an effect until you return from vPortSuppressTicksAndSleep().

What would be nice is if there was a callback from FreeRTOS to say that it had just been woken from sleep, where it was allowable to start the timers.

I think there is a 'post sleep' macro for this already?

Regards.


tickless mode timer problem - never sleeps

Posted by gmenhennitt on September 10, 2014

Thanks (again) for your reply.

There is indeed configPOSTSLEEPPROCESSING() (and the complementary configPRESLEEPPROCESSING()), but it isn't called anywhere.

Graham


tickless mode timer problem - never sleeps

Posted by rtel on September 11, 2014

The macros are normally called from the portable part of the tickless code, so not in the core FreeRTOS code. As you are not using your own tickless implementation (or at least, not one we provided) they probably have just not been added in, so you can add them in.

Regards.


tickless mode timer problem - never sleeps

Posted by gmenhennitt on October 3, 2014

I got a bit sidetracked, but I finally got back to this. Attached is a stripped down version of my program which demonstrates the problem. I drive a few output bits (Port 8, bits 4, 5,& 6) to indicate the state. P8.4 is driven to show when I'm in sleep mode. I attach a logic analyser to those pins to see it more easily.

If you build and run the project, you can see that it spends half its time asleep and the other half awake. It should sleep almost all the time. It seems that stopping the timer from inside the timer callback alternately allows sleeping or prevents it.

Thanks for your assistance.

Regards, Graham

Attachments

timertest.7z (106290 bytes)

tickless mode timer problem - never sleeps

Posted by gmenhennitt on October 7, 2014

Well I think I've solved this particular problem myself. I was calling xTimerStart() from an ISR. When I don't do that, it sleeps correctly. It looks like portASSERTIFINTERRUPTPRIORITYINVALID() is a NoOp for the MSP430, otherwise this would have been caught (I presume).

Sorry to trouble you.

Graham


tickless mode timer problem - never sleeps

Posted by gmenhennitt on November 19, 2014

Sorry to keep coming back to this, but I'm still having some problems.

Could you please clarify which FreeRTOS functions can be called from within the sleep function. For example, can I call xQueueSend() from inside vPortSuppressTicksAndSleep()?

What about xQueueSendFromISR()? And, if I called that, would the xHigherPriorityTaskWoken parameter to it ever be returned as true (since the scheduler is stopped)?

If it can be returned as true, can I call portYIELDFROMISR(true) from inside vPortSuppressTicksAndSleep(). If so, what would be the effect? I suspect that the answer is that the vTaskStepTick() at the bottom of vPortSuppressTicksAndSleep() would cause a context switch. Is that right?

Thanks again for your assistance, Graham


tickless mode timer problem - never sleeps

Posted by rtel on November 19, 2014

Could you please clarify which FreeRTOS functions can be called from within the sleep function. For example, can I call xQueueSend() from inside vPortSuppressTicksAndSleep()?

Remember vPortSuppressTicksAndSleep() is [necessarily, to prevent race conditions when sleep mode is exited] called with the scheduler suspended. There is a general rule in FreeRTOS that says don't call API functions with the scheduler suspended or from within a critical section. That is a general rule - to which there are exceptions - but listing the exceptions would require very detailed knowledge of the internal workings. Consider however what would happen if you wrote to a queue and the write operation attempted to switch to another task - the switch would not occur because the scheduler was suspended, which could lead to logic errors. Also consider the effect of waking a task when the scheduler had already told you you could idle for 'n' ticks because there were no tasks wanting to run, another logic error would ensue.

So there is no easy answer - if you have a block time of 0, and don't wake a task it would probably be ok, otherwise it may well not be ok.

What about xQueueSendFromISR()? And, if I called that, would the xHigherPriorityTaskWoken parameter to it ever be returned as true (since the scheduler is stopped)?

If it was called from an interrupt (as intended) then that should be fine as the interrupt will have brought the system out of sleep mode already. If you follow the standard tickless template then interrupt are prevented from happening at critical times when it would cause a problem anyhow.

If the interrupt brought a task out of the Blocked state the context switch would be held pending (by the kernel) until the scheduler was unsuspended - which will happen automatically when the 'suppress ticks and sleep' function exits.

If it can be returned as true, can I call portYIELDFROMISR(true) from inside vPortSuppressTicksAndSleep(). If so, what would be the effect? I suspect that the answer is that the vTaskStepTick() at the bottom of vPortSuppressTicksAndSleep() would cause a context switch. Is that right?

Almost - as just mentioned the context switch would happen after that, when the suppress ticks function itself exits.

Regards.


tickless mode timer problem - never sleeps

Posted by gmenhennitt on November 21, 2014

Thanks. Pretty much as I expected.

Graham


[ Back to the top ]    [ About FreeRTOS ]    [ Sitemap ]    [ ]




Copyright (C) Amazon Web Services, Inc. or its affiliates. All rights reserved.

Latest News

FreeRTOS kernel V10 is available for immediate download. Now MIT licensed.


FreeRTOS Partners

ARM Connected RTOS partner for all ARM microcontroller cores

IAR Partner

Microchip Premier RTOS Partner

RTOS partner of NXP for all NXP ARM microcontrollers

STMicro RTOS partner supporting ARM7, ARM Cortex-M3, ARM Cortex-M4 and ARM Cortex-M0

Texas Instruments MCU Developer Network RTOS partner for ARM and MSP430 microcontrollers

OpenRTOS and SafeRTOS