FreeRTOS 9.0.0 + ARM Cortex M4F + Tickless sleep + MPU

odman wrote on Tuesday, January 31, 2017:

FreeRTOS version 9.0.0
MCU: EFR32FG1P133F256GM48-C0, contains ARM Cortex M4 with MPU and FPU (a.k.a. M4F)
I use GCC.
Looking at the provided ports, MPU is only supported in portable\GCC\ARM_CM4_MPU
and Tickless sleep only in portable\GCC\ARM_CM4F
I would like to use both MPU and Tickless sleep. Has anyone attempted this, or is there
a reason that it would be impossible to do?
If there is an issue related to the FPU I think I can manage with FPU disabled.
On a side note: You can find bits and pieces of code online, but it’s for old versions of FreeRTOS and for M3 or other cores, so it won’t even compile with 9.0.0. I’m not sure that’s the right battle to fight either.
I’d appreciate any pointers and suggestions, and of course source code would be fantastic!

Many thanks!
Knut

rtel wrote on Tuesday, January 31, 2017:

is there
a reason that it would be impossible to do?

Can’t think of any reasons why it would be impossible.

On a side note: You can find bits and pieces of code online, but it’s
for old versions of FreeRTOS and for M3 or other cores, so it won’t even

Do you bits of M4F with MPU support specifically?

odman wrote on Tuesday, January 31, 2017:

M4F+MPU was posted by Dr. Klaus Schaefer on April 8, 2013:
https://interactive.freertos.org/hc/en-us/community/posts/210029306-ARM-Cortex-M4F-MPU-plus-FPU-port-with-fast-interrupt-response-time
There is a subdirectory portable/GCC/ARM_CM4_MPU_FPU. This however does not support tickless sleep.
You will find tickless sleep supported in portable/GCC/ARM_CM4F, but that port has no MPU support.
Unfortunately the ports were done for FreeRTOS version 7.4.0 and it’s not trivial to merge that code into 9.0.0.
It seems like FreeRTOS official release 9.0.0 has followed Dr. Schaefer’s pattern and you have to choose tickless or MPU but not both. There is also an older tickless demo port made for a Silicon Labs EFM32 Cortex M3, but without MPU. That chip is quite different though in terms of timers and core peripherals used.
I of course understand that it’s impossible to support every possible combination of CPU peripherals, but I’m a little bit at a loss to come up with a plan of attack.
Actually I’m planning to use FreeRTOS with the tasks running a state machine, so if I just can get FreeRTOS to go to sleep when the event queue is empty I’ll be fine. I can wake up on a low power timer in the chip. The Tickless sleep implementation looked like a good answer but maybe there are easier options available. Again, I need MPU but not necessarily FPU. Thanks much!

rtel wrote on Tuesday, January 31, 2017:

I would recommend using the official V9 MPU port as some work was done
to bring all the functions into the MPU version prior to that release,
then take the tickless code from a non MPU V9.0 port and add it in to
the MPU port (if you are using the default tickless code then it will
work on any Cortex-M, but the power saving you can achieve is limited by
the clock’s speed and width causing rapid overflows, and that you can’t
go into a power mode that stops the clock). Most of the tickless code
is in a separate function, so that part is easy to move across. Once
that function is moved across it won’t compile, so you will see which
other bits are needed from the compiler errors.

odman wrote on Thursday, February 16, 2017:

Hi and thanks for your help.
I have a question on the ports for ARM cortex M4 series.
In port.c, you have this code:

__attribute__(( weak )) void prvSetupTimerInterrupt( void )
{
	/* Calculate the constants required to configure the tick interrupt. */
	#if configUSE_TICKLESS_IDLE == 1
	{
		ulTimerCountsForOneTick = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ );
		xMaximumPossibleSuppressedTicks = portMAX_24_BIT_NUMBER / ulTimerCountsForOneTick;
		ulStoppedTimerCompensation = portMISSED_COUNTS_FACTOR / ( configCPU_CLOCK_HZ / configSYSTICK_CLOCK_HZ );
	}
	#endif /* configUSE_TICKLESS_IDLE */
	
	/* Configure SysTick to interrupt at the requested rate. */
	portNVIC_SYSTICK_LOAD_REG = ( configCPU_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL;
    ==============================^^^^^^^^^^^^^^^^^
	portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK | portNVIC_SYSTICK_INT | portNVIC_SYSTICK_ENABLE;
}

Shouldn’t the second line from the bottom read
portNVIC_SYSTICK_LOAD_REG = ( configSYSTICK_CLOCK_HZ …
Otherwise you may have different clock speed values for calculating ulTimerCountsForOneTick compared to what you load in the SYST_RVR register?
Also, and I realize this is an ARM question but I cannot find any information about this: how do you get SYS_TICK to clock from anything other than core CPU clock? I know you can use an external reference clock, but nowhere can I find how you select that clock to be for instance LFXCO?
Anyone knows?
Thanks much!
Knut

rtel wrote on Friday, February 17, 2017:

If you look at line 710 (at the time of writing) of the non MPU code you
will see it does use configSYSTICK_CLOCK_HZ. The MPU version looks
older and should be updated.

https://sourceforge.net/p/freertos/code/HEAD/tree/trunk/FreeRTOS/Source/portable/GCC/ARM_CM4F/port.c