Important note for GCC (and possibly other compiler) users:Some GCC libraries optimise memory copy and memory set (and possibly other) functions by making use of the wide floating point registers. Therefore, by default, any task that uses functions such as memcpy(), memcmp() or memset(), or uses a FreeRTOS API function such as xQueueSend() which itself uses memcpy(), will inadvertently corrupt the floating point registers. Further, any interrupt that calls a FreeRTOS queue or semaphore function will also corrupt the floating point context as they too make use of memcpy().
To avoid this either:
Essential information on interrupt prioritiesThe RTOS Cortex-A port implements a full interrupt nesting scheme, the behaviour of which is dependent on the configMAX_API_CALL_INTERRUPT_PRIORITY setting. configMAX_API_CALL_INTERRUPT_PRIORITY must be defined in FreeRTOSConfig.h.
Interrupts assigned a priority at or below the priority set by configMAX_API_CALL_INTERRUPT_PRIORITY can call interrupt safe FreeRTOS API function, and will nest. Interrupts safe FreeRTOS API function are those that end in "FromISR" (FreeRTOS maintains a separate interrupt API to ensure interrupt entry is as efficient and simple as possible).
Interrupts assigned a priority above the configMAX_API_CALL_INTERRUPT_PRIORITY setting will not be effected by RTOS critical sections, and will nest, but cannot call any FreeRTOS API functions.
Special Note 1: In ARM interrupt controllers, higher numeric interrupt priority values denote lower logical interrupt priorities. Therefore an interrupt priority of 5 is lower than an interrupt priority of 4. If configMAX_API_CALL_INTERRUPT_PRIORITY is set to 5, then it is correct for an interrupt handler that calls an interrupt safe API function to be assigned a priority of 5 or 6, but it is not correct for it to be assigned a priority of 4.
Special Note 2: The interrupt controller's internal representation of priority bits can be ignored. If the interrupt controller implements 32 unique priority levels, then the only valid values for configMAX_API_CALL_INTERRUPT_PRIORITY are 1 to 30. Likewise, if the interrupt controller implements 16 unique priority levels then valid values are 1 to 14.
Special Note 3: Interrupt controllers that can sub-divide interrupt priority bits into preemption priorities and sub-priorities should have all bits configured as preemption priority. In the ARM generic interrupt controller (GIC) this means the interrupt controller's binary point register must be set to 0.
ARM Cortex-A specific FreeRTOSConfig.h settingsThe following settings must be included in FreeRTOSConfig.h:
Note: If there is an official demo for the Cortex-A9 processor you are using then the FreeRTOSConfig.h file provided with the demo will already contain the correct settings.
Configuring and installing the RTOS tick interruptEvery official FreeRTOS demo that targets an ARM Cortex-A based embedded processor includes code to configure a timer to generate the RTOS tick interrupt, and install the FreeRTOS tick interrupt handler. The following information is only required if you need to change the provided implementation.
The macro configSETUP_TICK_INTERRUPT() is called by the RTOS kernel port layer. configSETUP_TICK_INTERRUPT() must be #defined in FreeRTOSConfig.h to configure a peripheral to generate a periodic interrupt at the frequency set by the configTICK_RATE_HZ FreeRTOSConfig.h setting. FreeRTOS_Tick_Handler() must then be installed as the interrupt's handler function. For example:
Interrupt handlingEvery official FreeRTOS demo that targets an ARM Cortex-A based embedded processor includes code that handles interrupts. The following information is only required if you need to change the provided implementation.
Interrupt entry, nesting, and exit code is provided by the RTOS kernel port layer. After an interrupt has been entered the RTOS port layer executes a callback function that must be provided by the application writer. Individual interrupt service routines can then be called by the callback function. An example is provided below.
The callback function can be called either vApplicationIRQHandler(), or if you are using GCC and FreeRTOS V9.0.0 or later, vApplicationFPUSafeIRQHandler().
The callback function (vApplicationIRQHandler() or vApplicationFPUSafeIRQHandler()) is called with interrupts disabled, but can (and in most cases should) enable interrupts. Below is an example implementation:
Installing the FreeRTOS IRQ and SWI (SVC) interrupt handlersFreeRTOS_IRQ_Handler() must be installed as the Cortex-A's IRQ handler.
FreeRTOS_SWI_Handler() must be installed as the Cortex-A's SWI (SVC) handler.
If it is not possible to edit the interrupt vector code then map the FreeRTOS handlers to the required handler names using #defines in FreeRTOSConfig.h. For example, if the installed handlers are called IRQ_Handler() and SWI_Handler() respectively, then the FreeRTOS handlers can be mapped to these names by adding the following two lines to FreeRTOSConfig.h.
ARMv7A processor modes and stacksThe C start up code must, as a minimum, configure stacks for the IRQ and Supervisor modes of the Cortex-A processor. main() must be called from a privileged mode, preferably Supervisor mode.
It is not necessary to allocate a stack to User/System mode unless main() is called from System mode (main() must not be called from User mode). If a stack is allocated to User/System mode it will not be used after the RTOS kernel has been started.
The RTOS stack overflow detection functionality only detects overflows in task stacks, not IRQ or Supervisor stacks.
ARMv8A exception levelsCurrently:
Copyright (C) Amazon Web Services, Inc. or its affiliates. All rights reserved.
NXP tweet showing LPC5500 (ARMv8-M Cortex-M33) running FreeRTOS.
Meet Richard Barry and learn about running FreeRTOS on RISC-V at FOSDEM 2019
Version 10.1.1 of the FreeRTOS kernel is available for immediate download. MIT licensed.
View a recording of the "OTA Update Security and Reliability" webinar, presented by TI and AWS.
FreeRTOS and other embedded software careers at AWS.