Using FreeRTOS on ARM Cortex-A9 Embedded Processors
That use a proprietary interrupt controller

Introduction

Some ARM Cortex-A processors incorporate ARM's own Generic Interrupt Controller (GIC), while others incorporate proprietary interrupt controllers. Separate web pages are provided to give instructions on using the RTOS in both scenarios. This page provides information on running the RTOS on an ARM Cortex-A embedded processor that does not incorporates ARM's own Generic Interrupt Controller (GIC). See also the web page that describes running the RTOS on an ARM Cortex-A embedded processor that also includes ARM's GIC.

On this page:


Features of the FreeRTOS ARM Cortex-A RTOS port

The FreeRTOS ARM Cortex-A port for microprocessors that use a proprietary interrupt controller:


Using the floating point unit (FPU)

Tasks that make use of the hardware floating point unit must call portTASK_USES_FLOATING_POINT() before any floating point calculations are executed. It is only necessary to call portTASK_USES_FLOATING_POINT() once per task. For example:

void vATaskFunction( void *pvParameters ) { double x, y; /* This task is going to use floating point operations. Therefore it calls portTASK_USES_FLOATING_POINT() once on task entry, before entering the loop that implements its functionality. From this point on the task has a floating point context. */ portTASK_USES_FLOATING_POINT(); /* Enter the loop that implements the task's function. */ for( ;; ) { /* portTASK_USES_FLOATING_POINT() has already been called, so it is safe to use the floating point x and y variables here... */ x = [whatever]; y = [whatever]; } } Calling portTASK_USES_FLOATING_POINT() before any floating point calculations are performed


It should be noted that, by default, the Cortex-A9 port does not support the use of the floating point unit in interrupts. If it is necessary to use the floating point unit in interrupts then it will also be necessary to save the entire floating point context to the stack on entry to each (potentially nested) interrupt.


ARM Cortex-A specific FreeRTOSConfig.h settings

The following settings must be included in FreeRTOSConfig.h. Note these settings are specific to the ARM Cortex-A RTOS port for processors that use a proprietary interrupt controller. The settings for the RTOS port for ARM Cortex-A processors that use the ARM GIC are different because they also configure the GIC.

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 interrupt

Every 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 handling function. For example:

/* Implement a function in a C file to generate a periodic interrupt at the required frequency. */ void vSetupTickInterrupt( void ) { /* FreeRTOS_Tick_Handler() is itself defined in the RTOS port layer. An extern declaration is required to allow the following code to compile. */ extern void FreeRTOS_Tick_Handler( void ); /* Assume TIMER1_configure() configures a hypothetical timer peripheral called TIMER1 to generate a periodic interrupt with a frequency set by its parameter. */ TIMER1_configure( configTICK_RATE_HZ ); /* Next assume Install_Interrupt() installs the function passed as its second parameter as the handler for the peripheral passed as its first parameter. */ Install_Interrupt( TIMER1, FreeRTOS_Tick_Handler ); } Defining a function that configures a timer to generate a periodic tick

/* Given the function definition above, add the following line to FreeRTOSConfig.h. */ #define configSETUP_TICK_INTERRUPT() vSetupTickInterrupt() #defining configSETUP_TICK_INTERRUPT() to the function that generates the periodic tick


Interrupt handling

Official RTOS demo applications include example interrupt handlers. Refer to the official RTOS demo application for the processor in use to find examples and reference source code.

Interrupt entry, nesting, and exit is managed by the RTOS kernel port layer so interrupt handlers provided by the application writer can be standard C functions. Specific interrupt related pragmas, assembly code wrappers or attribute qualifiers are not required.

Interrupt handling routes provided by the application writer are called by the RTOS with interrupts enabled.

Also see the description of the configINTERRUPT_VECTOR_ADDRESS FreeRTOSConfig.h setting above.


Installing the FreeRTOS IRQ and SWI (SVC) interrupt handlers

FreeRTOS_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.

#define FreeRTOS_IRQ_Handler IRQ_Handler #define FreeRTOS_SWI_Handler SWI_Handler Mapping the FreeRTOS interrupt handler names to alternative handler names


Cortex-A processor modes and stacks

The 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.