Optimized FreeRTOS: Stack Check and SysTick for ARM Cortex Cores

The ARM Cortex specification includes the ‘SysTick’ (System Tick Timer): a dedicated system timer which is intended to be used as time base for an RTOS. While technically it would be possible to use any periodic interrupt timer, I’m using as well the SysTick for my FreeRTOS ARM ports. And because Processor Expert includes a nice timer interface, I’m using the TimerUnit_LDD:

TimerUnit LDD for SysTick

TimerUnit LDD for SysTick

While this is great for flexibility, it has its price in efficiency. That TimerUnit_LDD adds overhead. So I want to get rid of the TimerUnit_LDD and use a more efficient way.

Direct SysTick Implementation

Instead of using the TimerUnit_LDD, I want to directly use the SysTick. As SysTick is part of the ARM core, the implementation is pretty much the same for every ARM core, so why not using it directly?

So I decided to introduce an extra property:

SysTick Boolean Property

SysTick Boolean Property

If that ‘SysTick’ is set to ‘yes’ (default), it directly uses the SysTick of the ARM core, and no need to configure a TimerUnit_LDD:

No TimerUnit_LDD needed

No TimerUnit_LDD needed

Inside the port, it directly accesses the SysTick hardware and is not using the TimerUnit_LDD interface.

The positive side effect is:

  1. Not to worry about aligning the RTOS frequency with the timer frequency.
  2. No need to select a free timer: it is always using the SysTick.
  3. Better runtime performance (no need for extra push/pop in interrupt).
  4. And best of all: it saves 200 bytes of FLASH and 16 bytes of RAM (ARM Cortex M0+). 🙂 🙂

💡 If running into an error message about #include “RTOSTICKLDD1.h” in Events.c, Events.h or Processor Expert: It seems that in some cases Processor Expert does not remove the include, as that file is not needed and not generated any more. In that case, you can simply remove it by hand from the source file.

Stack Overflow Checking

FreeRTOS has the feature to check for a stack overflow at the time of a context switch which is incredible helpful. Still, sometimes I want to disable this for performance. So far I was able to do this with disabling the stack overflow event:

Disabling Stack Overflow Hook

Disabling Stack Overflow Hook

Now it is possible to select ‘none’ directly in the properties:

No Stack Overflow Checking

No Stack Overflow Checking

And in an ARM Cortex-M0+ application with GNU gcc, this saves 52 bytes of FLASH :-).

Summary

The above changes are not very big, but making usage of FreeRTOS especially on ARM Cortex better and easier, especially with Processor Expert. What I have additionally in my mind, but not done yet is to SysTick as the performance counter: now a dedicated timer is used. And of for low power tickless idle mode to use a different timer than SysTick. So still room for improvements 🙂

Happy Ticking 🙂

Advertisements

7 thoughts on “Optimized FreeRTOS: Stack Check and SysTick for ARM Cortex Cores

  1. Hi Erich,
    thanks again for this tutorial and this news.
    I have read plenty of articles “featuring” FreeRTOS and some other with MQX…
    By the way I was wandering: is there a criterion by which you should prefer MQX, MQX Lite or FreeRTOS on Kinetis K and KL?

    Best Regards
    Roberto

    Like

    • Hi Roberto,
      it all depends on your requirements. FreeRTOS is very well designed for small systems, and is so effient that can run on a system with say 3-4 KByte of FLASH and less than 1 KByte of RAM, and on 8bit and 32bit processors. FreeRTOS is ‘just’ the RTOS, and does not come with additional drivers, but you can add any drivers (like SPI, UART, etc) you like. MQX is more like QNX or other ‘bigger’ RTOS, and much heavier (it needs much more RAM and FLASH than FreeRTOS, even without the drivers). Yes, MQX has advanced features, but you might not need them. That’s why Freescale has stripped down the MQX to ‘MQXlite’: it is still heavier than an RTOS like FreeRTOS, but uses the same API. And as FreeRTOS, MQXlite does not come with the drivers or memory manager. And there is a difference in licensing: FreeRTOS is open source with a very perimissible license which allows it for you to be used on any processor, under any circumstances. While MQX is not open source (source code is provided, but it is not open source), and you are only allowed to use MQX for Freescale processors free of charge. The other thing is: FreeRTOS is by far the most popular operating system (see http://www.eetimes.com/document.asp?doc_id=1263083)
      I hope this helps.

      Like

  2. I am having difficulty with importing the FreeRTOS component into my project. The import of the components into the library went smoothly. However, when I drag the FreeRTOS component into the project I get an error: “Error during adding shared component/template “Utility”. Component is either missing or corrupted”. I re-downloaded the PEupd and experienced the same result. I can see the utility files in \ProgramData\Processor Expert\CWMCU_PE5_00\Beans\FreeRTOS TIA, Eric

    Like

    • Hi Eric,
      Are you using the 24.09 files I uploaded yesterday on https://github.com/ErichStyger/mcuoneclipse/tree/master/PEupd?
      I had another report about the Utility component the day before, not sure what was causing this, but the 24.09 files seemed to fixe it.
      Maybe I’m running into a Processor Expert problem with the current process of importing so many components, not sure.
      I send you by email the Utility component as single package, just as an option.
      Additionally, below you find the list of files which make up that component. Maybe some are not installed somehow?
      C:\ProgramData\Processor Expert\CWMCU_PE5_00\Beans\Utility\Utility.tps
      C:\ProgramData\Processor Expert\CWMCU_PE5_00\Beans\Utility\.gitignore
      C:\ProgramData\Processor Expert\CWMCU_PE5_00\Beans\Utility\Utility.bean
      C:\ProgramData\Processor Expert\CWMCU_PE5_00\Beans\Utility\Utility.bmp
      C:\ProgramData\Processor Expert\CWMCU_PE5_00\Beans\Utility\Utility.html
      C:\ProgramData\Processor Expert\CWMCU_PE5_00\Beans\Utility\Utility_b.gif
      C:\ProgramData\Processor Expert\CWMCU_PE5_00\Beans\Utility\UtilityEvents.html
      C:\ProgramData\Processor Expert\CWMCU_PE5_00\Beans\Utility\UtilityMethods.html
      C:\ProgramData\Processor Expert\CWMCU_PE5_00\Beans\Utility\UtilityProperties.html
      C:\ProgramData\Processor Expert\CWMCU_PE5_00\Drivers\Utility.src
      C:\ProgramData\Processor Expert\CWMCU_PE5_00\Drivers\sw\Utility.drv
      C:\ProgramData\Processor Expert\CWMCU_PE5_00\Drivers\Common\UtilitySettings.Inc
      C:\ProgramData\Processor Expert\CWMCU_PE5_00\Drivers\Common\UtilityAbstract.Inc
      C:\ProgramData\Processor Expert\CWMCU_PE5_00\Drivers\sw\CommonSupport.prg
      C:\ProgramData\Processor Expert\CWMCU_PE5_00\Drivers\Common\Utilitystrcpy.Inc
      C:\ProgramData\Processor Expert\CWMCU_PE5_00\Drivers\Common\Utilitystrcat.Inc
      C:\ProgramData\Processor Expert\CWMCU_PE5_00\Drivers\Common\UtilityNum16sToStr.Inc
      C:\ProgramData\Processor Expert\CWMCU_PE5_00\Drivers\Common\UtilityNum16sToStrFormatted.Inc
      C:\ProgramData\Processor Expert\CWMCU_PE5_00\Drivers\Common\UtilitystrcatNum16s.Inc
      C:\ProgramData\Processor Expert\CWMCU_PE5_00\Drivers\Common\UtilitystrcatNum16sFormatted.Inc
      C:\ProgramData\Processor Expert\CWMCU_PE5_00\Drivers\Common\UtilitystrcatNum8Hex.Inc
      C:\ProgramData\Processor Expert\CWMCU_PE5_00\Drivers\Common\UtilitystrcatNum16Hex.Inc
      C:\ProgramData\Processor Expert\CWMCU_PE5_00\Drivers\Common\UtilitystrcatNum32s.Inc
      C:\ProgramData\Processor Expert\CWMCU_PE5_00\Drivers\Common\UtilityNum32sToStr.Inc
      C:\ProgramData\Processor Expert\CWMCU_PE5_00\Drivers\Common\UtilitystrcatNum32Hex.Inc
      C:\ProgramData\Processor Expert\CWMCU_PE5_00\Drivers\Common\UtilityIsLeapYear.Inc
      C:\ProgramData\Processor Expert\CWMCU_PE5_00\Drivers\Common\UtilityWeekDay.Inc
      C:\ProgramData\Processor Expert\CWMCU_PE5_00\Drivers\Common\Utilitychcat.Inc
      C:\ProgramData\Processor Expert\CWMCU_PE5_00\Drivers\Common\UtilitystrcatNum32u.Inc
      C:\ProgramData\Processor Expert\CWMCU_PE5_00\Drivers\Common\UtilityNum32uToStr.Inc
      C:\ProgramData\Processor Expert\CWMCU_PE5_00\Drivers\Common\UtilitystrcatNum32uFormatted.Inc
      C:\ProgramData\Processor Expert\CWMCU_PE5_00\Drivers\Common\UtilityNum32uToStrFormatted.Inc
      C:\ProgramData\Processor Expert\CWMCU_PE5_00\Drivers\Common\UtilitystrcatNum24Hex.Inc
      C:\ProgramData\Processor Expert\CWMCU_PE5_00\Drivers\Common\UtilityReadEscapedName.Inc
      C:\ProgramData\Processor Expert\CWMCU_PE5_00\Drivers\Common\Utilityxatoi.Inc
      C:\ProgramData\Processor Expert\CWMCU_PE5_00\Drivers\Common\UtilityScanDate.Inc
      C:\ProgramData\Processor Expert\CWMCU_PE5_00\Drivers\Common\UtilityScanTime.Inc
      C:\ProgramData\Processor Expert\CWMCU_PE5_00\Drivers\Common\UtilityScanDecimal16uNumber.Inc
      C:\ProgramData\Processor Expert\CWMCU_PE5_00\Drivers\Common\UtilityScanDecimal8uNumber.Inc
      C:\ProgramData\Processor Expert\CWMCU_PE5_00\Drivers\Common\UtilityNum16uToStr.Inc
      C:\ProgramData\Processor Expert\CWMCU_PE5_00\Drivers\Common\UtilityNum8sToStr.Inc
      C:\ProgramData\Processor Expert\CWMCU_PE5_00\Drivers\Common\UtilityNum8uToStr.Inc
      C:\ProgramData\Processor Expert\CWMCU_PE5_00\Drivers\Common\UtilityNum16uToStrFormatted.Inc
      C:\ProgramData\Processor Expert\CWMCU_PE5_00\Drivers\Common\UtilityNum32sToStrFormatted.Inc
      C:\ProgramData\Processor Expert\CWMCU_PE5_00\Drivers\Common\UtilitystrcatNum16u.Inc
      C:\ProgramData\Processor Expert\CWMCU_PE5_00\Drivers\Common\UtilitystrcatNum16uFormatted.Inc
      C:\ProgramData\Processor Expert\CWMCU_PE5_00\Drivers\Common\UtilitystrcatNum32sFormatted.Inc
      C:\ProgramData\Processor Expert\CWMCU_PE5_00\Drivers\Common\UtilityScanDecimal32uNumber.Inc
      C:\ProgramData\Processor Expert\CWMCU_PE5_00\Drivers\Common\UtilitystrcatNum8u.Inc
      C:\ProgramData\Processor Expert\CWMCU_PE5_00\Drivers\Common\UtilitystrcatNum8s.Inc
      C:\ProgramData\Processor Expert\CWMCU_PE5_00\Drivers\Common\Utilitystrcmp.Inc
      C:\ProgramData\Processor Expert\CWMCU_PE5_00\Drivers\Common\Utilitystrncmp.Inc
      C:\ProgramData\Processor Expert\CWMCU_PE5_00\Drivers\Common\Utilitystrlen.Inc
      C:\ProgramData\Processor Expert\CWMCU_PE5_00\Drivers\Common\UtilityScanHex32uNumber.Inc
      C:\ProgramData\Processor Expert\CWMCU_PE5_00\Drivers\Common\UtilityScanHex16uNumber.Inc
      C:\ProgramData\Processor Expert\CWMCU_PE5_00\Drivers\Common\UtilityScanHex8uNumber.Inc
      C:\ProgramData\Processor Expert\CWMCU_PE5_00\Drivers\Common\Utilitystrtailcmp.Inc
      C:\ProgramData\Processor Expert\CWMCU_PE5_00\Drivers\Common\UtilitystrCutTail.Inc
      C:\ProgramData\Processor Expert\CWMCU_PE5_00\Drivers\Common\UtilityScanHex8uNumberNoPrefix.Inc
      C:\ProgramData\Processor Expert\CWMCU_PE5_00\Drivers\Common\UtilitystrcatNum32sDotValue100.Inc

      Like

  3. Pingback: Tutorial: Using the FRDM-KL25Z as Low Power Board | MCU on Eclipse

  4. Hi Erich,

    did you experiment with the MPU features of FreeRTOS? In my understanding this is a even better way to detect stack overflows because it triggers immediately and not only when the scheduler runs again.
    It would also preserve the stack trace leading to the push or store instruction being responsible for the overflow.

    Like

What do you think?

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.