SAM4N ‘tickless idle’ losing ticks with Semaphore Take

I’m using v8.1.2 on an Atmel SAM4N, with ‘tickless idle’. I’ve used the implementation of the SAM4L lowpowertickmanagement.c from v8.0.1; modified – because it doesn’t have an AST – to the SAM4N’s similarly-slow-running RTT. The tick rate is 128Hz. configEXPECTEDIDLETIMEBEFORE_SLEEP is set to 5. This seems to be working, but I’ve encountered an issue with one particular task (there’s only 3 in the app so far) which is waiting on a semaphore (xSemaphoreCreateBinary) given by an ISR: the tick count, comparing it with real time, is running 50% slow. In my current set-up the semaphore is never given (and I’ve disabled the interrupt). The timeout on the xSemaphoreTake is 1sec; and the task loop then has a further 1sec vTaskDelay. If I add a delay to the task before it enters its for loop, then the tick rate is fine until that delay ends. Now there may be a problem with my lowpowertick_management.c, but I’ve discovered that if I change the xSemaphoreTake() to a plain vTaskDelay() then the problem goes away. Which makes me instead suspect something kernel-related – shouldn’t they then be amounting, in broad terms, to the same thing? i.e. delay the task for 1sec. I haven’t spotted anything relevant in the change history, but is there a fix/update I’ve missed? I’m also unsure of the best way to dig to track the issue down further..?

SAM4N ‘tickless idle’ losing ticks with Semaphore Take

Oh, and the other ‘interesting’ factor – if I enable FreeRTOS+Trace in the app, then the issue also disappears…

SAM4N ‘tickless idle’ losing ticks with Semaphore Take

It is not quite clear to me how the issue is manifesting itself. Hopefully some questions and answers will make it clearer:
I’m using v8.1.2 on an Atmel SAM4N, with ‘tickless idle’. I’ve used the implementation of the SAM4L lowpowertick_management.c from v8.0.1; modified – because it doesn’t have an AST – to the SAM4N’s
Did you check the latest version of FreeRTOS to see if the tickless implementation had changed? I just did – and found in fact it had, with an additional line being added – being line 384 in this file: http://sourceforge.net/p/freertos/code/HEAD/tree/trunk/FreeRTOS/Demo/CORTEXM4ATSAM4LAtmelStudio/src/SAM4Llowpowertickmanagement.c
This seems to be working, but I’ve encountered an issue with one particular task (there’s only 3 in the app so far) which is waiting on a semaphore (xSemaphoreCreateBinary) given by an ISR:
I presume you are using xSemaphoreGiveFromISR(), rather than xSemaphoreGive(). If you were using the latest FreeRTOS version you would also be able to get a lot more run time checking of interrupt priorities (the most common cause of issues on Cortex-M) by having configASSERT() defined.
the tick count, comparing it with real time, is running 50% slow.
….and is that also the case when configUSETICKLESSIDLE is set to 0?
In my current set-up the semaphore is never given (and I’ve disabled the interrupt). The timeout on the xSemaphoreTake is 1sec; and the task loop then has a further 1sec vTaskDelay. If I add a delay to the task before it enters its for loop, then the tick rate is fine until that delay ends.
Hmm. That does sound like an problem in your tickless idle implementation then, as that is when the tick frequency gets set back to its normal ‘ticking’ frequency. Could you also try this using the default tickless idle mode, which is build into the Cortex-M4 port layer (best to use the latest version). The power saving will not be as great, but it will be good for comparison as a test.
Now there may be a problem with my lowpowertick_management.c, but I’ve discovered that if I change the xSemaphoreTake() to a plain vTaskDelay() then the problem goes away.
Assuming the semaphore has been created, then timing out on a semaphore should indeed behave the same as calling vTaskDelay(). The underlying mechanisms in the code’s implementation are close to being the same. Regards.

SAM4N ‘tickless idle’ losing ticks with Semaphore Take

Thanks for the quick reply. “Did you check the latest version of FreeRTOS to see if the tickless implementation had changed? I just did – and found in fact it had, with an additional line being added – being line 384 in this file:” I did see this addition in an online post, but I’m unsure (I’ll re-check) whether its relevant to the different timer which I have. [And it’s accepted that you can’t comment a great deal on chip specifics]. “I presume you are using xSemaphoreGiveFromISR(), rather than xSemaphoreGive().” Sorry, yes – I abbreviated it in my text. (And I’m not even enabling the interrupt anyway now). “If you were using the latest FreeRTOS version you would also be able to get a lot more run time checking of interrupt priorities (the most common cause of issues on Cortex-M) by having configASSERT() defined.” I’ll look at upgrading. I haven’t checked without tickles idle (or with the default) – to be honest, because it’s critical to the app, I’ve been using tickless pretty much from the outset. “That does sound like an problem in your tickless idle implementation then, as that is when the tick frequency gets set back to its normal ‘ticking’ frequency” Is that the case? As I understood it [with this implementation], it’s always the slow tick which is being used, so the frequency is fixed.

SAM4N ‘tickless idle’ losing ticks with Semaphore Take

“That does sound like an problem in your tickless idle implementation then, as that is when the tick frequency gets set back to its normal ‘ticking’ frequency” Is that the case? As I understood it [with this implementation], it’s always the slow tick which is being used, so the frequency is fixed.
Right – that could well be the case for the SAM4L. It is the place where the register that sets the time the next interrupt is written to in any case, although granted the value written to the register is probably only calculated once at initialisation or compile time, and then just reused – so shouldn’t be wrong if it was correct the first time it was used. Worth trying with the default tickless implementation all the same though, and it could narrow down the source of the issue. Regards.

SAM4N ‘tickless idle’ losing ticks with Semaphore Take

A follow-on re. upgrading FreeRTOS – I’m using Atmel Studio, which is always a PITA. Am I right in thinking that the versions of port.c and portmacro.h I should be pulling in for this processor are the ones in ‘ARM_CM3’? (I think that’s what I did last time I upgraded).

SAM4N ‘tickless idle’ losing ticks with Semaphore Take

I can’t recall if the SAM4N has a floating point unit or not. If it does then use the port layer files from FreeRTOS/Source/portable/GCC/ARMCM4F. On the other hand, if it does *not* have a floating point unit then use the files from FreeRTOS/Source/portable/GCC/ARMCM3. Regards.

SAM4N ‘tickless idle’ losing ticks with Semaphore Take

Yep – no FPU. Thanks.

SAM4N ‘tickless idle’ losing ticks with Semaphore Take

Ok, the default tickless implementation works ok [albeit my app is now stripped down a lot!]. Even with the latest kernel though, my low power tickless goes awry. It’s odd that xSemaphoreTake() vs. vTaskDelay() makes a difference; similarly enabling FreeRTOS+Trace. Makes me wonder if it relates to execution time entering/exiting the tickless state, except both presumably involve extra instructions. Any thoughts, from these RTOS perspectives, as to what area may being getting fouled up…?

SAM4N ‘tickless idle’ losing ticks with Semaphore Take

Nothing comes to mind. It is very curious that the tick frequency doubles (or halves, I forgot what you said now). Can you view the registers in the peripheral used to generate the tick at the time the tick frequency is executing at the wrong frequency to see if any look incorrect (the compare match value, a divider, or something). Although, that assumes the tick is really at the wrong frequency, it could alternatively be the code that stops the tick or re-starts the tick that is somehow generating additional interrupts so in fact the clock is correct, but the additional interrupts make it appear as if it were to fast (or slow, or whatever). Are you sure the interrupt that brings the system out of sleep is being cleared correctly, and not executing twice? Regards.

SAM4N ‘tickless idle’ losing ticks with Semaphore Take

I do suspect it’s something to do with the reload/restart logic. I did previously see the ISR being entered twice at a time, which I thought I’d corrected. It may be that it is still happening on some occasions (as the rate error seems to be somewhat variable – especially depending what other code/tasks I have in there) – another close inspection needed!

SAM4N ‘tickless idle’ losing ticks with Semaphore Take

Does look like a problem with the RTT – I can reproduce what looks like similar symptoms with just a simple [FreeRTOS-less] test app. Support ticket opened with Atmel! I do have a question about the tickless SAM4L example in FreeRTOS though – is there someone here (i.e. authors) who might be able to clarify a part of the code?

SAM4N ‘tickless idle’ losing ticks with Semaphore Take

“yes”. Which part?

SAM4N ‘tickless idle’ losing ticks with Semaphore Take

The part of vPortSuppressTicksAndSleep() after the sleep has ended due to a tick interrupt: “if( ulTickFlag != pdFALSE ) { …”. I’m just puzzled by resetting “the alarm value with whatever remains of this tick period” – the cpu has woken because of a tick, so hasn’t the ISR already set the alarm for the next tick? Why is it necessary to re-set it? Or in other words, isn’t the alarm value just going to be set to the value it already has?

SAM4N ‘tickless idle’ losing ticks with Semaphore Take

I don’t have the code in front of me right now, but could it be because the MCU will have been woken part way through a tick period, but the interrupt itself didn’t take that into account so reset the wake time for a complete tick period (rather than the remainder of the partial tick period)? Regards.

SAM4N ‘tickless idle’ losing ticks with Semaphore Take

I think that case is the ‘else’ part.