Use vPortSetupTimerInterrupt to update systick after clock change

Hello,

At the moment I’m optimizing a device consumption (STM32 cortex M7). I already have Standby mode implemented for when the device is idle.

Now I’m also optimizing consumption during “wake up” mode. I’ve identified that most of the time we can be in “low performance” and for that I’ve configured the CPU clock at 120MHz. At some point, we need to run some algorithm that needs full power and for that I go to 480MHz.

I managed to do this switch, by setting first HSI as sysclk, changing PLL values, update peripherals, etc.

However, I’ve seen that FreeRTOS timers get messed up. I understand that this is due to ticks going faster than the expected 1ms during this “high-performance” moments.

It seems I managed to solve this by calling vPortSetupTimerInterrupt() (port.c) every time I update the system clock (this way getting SYSTICK_LOAD_REG updated). However, for this, I had to move the function declaration to portable.h (to have access to it from my code).

Is this the right approach? or should I avoid making changes in port.c, portable.h, etc.? as it has a weak definition, I was going to define a new vPortSetupTimerInterrupt but then I realize I needed access to variables such as “ulTimerCountsForOneTick”…

For the future, I will add a TODO to run the system tick with another source, so to be able to change PLL/CPU clocks freely without this impact on FreeRTOS timings. But at the moment I need to solve it somehow simpler as I don’t have time for a proper full implementation.

Thanks!

Normally, the routines in port.c are marked as “weak”, so your application code can override those routines with your own versions, rather than changing the code in port.c. Once you replace those, you will probably find that you don’t need the copy of the variable in port.c, as it won’t be used anywhere, and you just need to declare your own variable in your code.

Also, replacing the timer should be very simple, and I find that most of the parts have a “Low Power” timer that works much better for the system tick in this sort of application (as long as you don’t need a precise 1ms time base, but can use a 1024 Hz time base), and it is less work switching to it then trying to handle the changing clock on the timer based on the processor clock

I’m not sure what you mean. For example, variable ulTimerCountsForOneTick is used many times in vPortSuppressTicksAndSleep() (all happening in port.c). If I do my own implementation of vPortSetupTimerInterrupt it would be mostly to update systick registers and count, but what would happen with ulTimerCountsForOneTick value?

On the other hand, thanks for the advice, I’ll try to implement the RTC clock for the system tick.

It is a file static in port.c. If you need it in your implementation of vPortSuppressTicksAndSleep, you should be able to define it in your implementation file.

I would suggest not to modify the FreeRTOS files as it would be difficult for you to update to a newer FreeRTOS version later.