Download FreeRTOS
 

Quality RTOS & Embedded Software

KERNEL
WHAT'S NEW
Simplifying Authenticated Cloud Connectivity for Any Device.
Designing an energy efficient and cloud-connected IoT solution with CoAP.
Introducing FreeRTOS Kernel version 11.0.0:
FreeRTOS Roadmap and Code Contribution process.
OPC-UA over TSN with FreeRTOS.

Cortex-A53 Xilinx UltraScale MPSoC
64-bit (AArch64) RTOS Demo
[RTOS Ports]


Xilinx UltraScale MPSoC with four 64-bit ARM Cortex-A53 Cores and 2 32-bit ARM Cortex-R5 real time cores

The Xilinx SDK (Software Development Kit) includes wizards that create FreeRTOS projects for all the cores found on the Zynq UltraScale MPSoC, which includes ARM Cortex-A53 (AArch64, 64-bit), ARM Cortex-R5, and Microblaze processors.


Introduction

This page documents a FreeRTOS demo application that targets a 64-bit ARM Cortex-A53 (AArch64) core on a Xilinx Zynq UltraScale+ MPSoC. A similar project that targets an ARM Cortex-R5 core on the same device is provided separately.

The demo uses a standalone BSP (which is the Board Support Package generated by the SDK), and builds FreeRTOS as part of the application. The hardware design project targets the ZCU102 Evaluation Kit.

FreeRTOS is also distributed as part of the Xilinx SDK package, and the SDK includes wizards to generate FreeRTOS for the UltraScale+ MPSoC's 64-bit ARM Cortex-A53, ARM Cortex-R5 and Microblaze cores. When the SDK generates a project FreeRTOS is built as part of the BSP, rather than part of the application. Instructions for this are also provided.

The 64-bit ARM Cortex-A53 FreeRTOS port implements a full interrupt nesting model, and supports the floating point unit (FPU).



IMPORTANT! Notes on using the FreeRTOS 64-bit ARM Cortex-A53 port

Please read all the following points before using this RTOS port.

  1. Source Code Organisation
  2. The Demo Application Functionality
  3. Build Instructions
  4. RTOS Configuration and Usage Details
Also see the FAQ My application does not run, what could be wrong?, and the page that provides instruction on using FreeRTOS on ARM Cortex-A embedded processors.

Source Code Organization

The FreeRTOS download contains the source code for all the FreeRTOS ports, and every demo application. That means it contains many more files than are required to use the Zynq UltraScale+ Cortex-A53 MPSoC port and demo application. See the Source Code Organization section of this web site for a description of the downloaded files, and information on creating a new project.

The directory structure used by the demo application is shown and described below. The root CORTEX_A53_64-bit_UltraScale_MPSoC directory is itself located in FreeRTOS/Demo.

CORTEX_A53_64-bit_UltraScale_MPSoC
  |
  +-RTOSDemo_A53              Contains the SDK project and C files specific to the demo.
  |
  +-RTOSDemo_A53_bsp          Contains the hardware board support package.
  |
  +-ZynqMP_ZCU102_hw_platform The ZCU102 hardware description.

	
Notes relating to the directory structure:

  • The projects contained in the ZynqMP_ZCU102_hw_platform and RTOSDemo_A53_bsp directories were created by the Xilinx SDK.

  • The RTOSDemo_A53 directory only contains the source files that are specific to the Zynq UltraScale+ MPSoC demo. The FreeRTOS source files, and the source files that implement tasks that are common to all demo applications, are located elsewhere in the directory tree. Therefore the project will only build when the default directory structure is unchanged. Also see the page that describes how to use virtual and linked paths in the Eclipse project explorer.



The Zynq UltraScale+ MPSoC ARM Cortex-A53 Demo Application

Functionality

The constant mainSELECTED_APPLICATION, which is #defined at the top of main.c, is used to switch between a simply Blinky style demo and a more comprehensive test and demo application.


Functionality with mainSELECTED_APPLICATION set to 0

If mainSELECTED_APPLICATION is set to 0 then main() will call main_blinky(), which is implemented in main_blinky.c.

main_blinky() creates a very simple demo that includes two tasks and one queue. One task uses the queue to repeatedly send the value 100 to the other task. The receiving task prints a message to the USB UART port (J83) each time the message is received. 115200 baud is used.

The message is sent to the queue every 200 milliseconds, so the message is printed to the UART every 200 milliseconds.


Functionality with mainSELECTED_APPLICATION set to 1

If mainSELECTED_APPLICATION is set to 1 then main() will call main_full(), which is implemented in main_full.c.

main_full() creates a comprehensive application that tests the RTOS port and demonstrates:

Most of the tasks created by the demo are from the set of standard demo tasks. These are used by all FreeRTOS demo applications, and have no specific functionality or purpose other than to demonstrate the FreeRTOS API being used, and test the RTOS port.

The following tasks are created in addition to the standard demo tasks:

  • Interrupt nesting test tasks

    Two timers are used to test interrupt nesting, and test RTOS queues being used from nested interrupts.

  • Register test tasks

    The register test tasks test the RTOS context switch mechanism by first filling each ARM Cortex-A53 register (including the floating point registers) with a known and unique value, then repeatedly checking that the value originally written to the register remains in the register for the lifetime of the task. The nature of these tasks necessitates that they are written in assembly.

  • A 'check' task

    The check task periodically queries the standard demo tasks, and the register test tasks, to ensure they are functioning as intended - then prints a status message to the USB UART (J83). 115200 baud is used.

    The output generated when the RTOS demo is executed on a 64-bit ARM Cortex-A53 core on the Zynq UltraScale+ MPSoC
    The output generated by the full demo


Hardware setup

All four switches on bank SW6 need to be set toward the centre of the board in order to enable downloading and executing over the JTAG interface.



Build Instructions - Using the Official FreeRTOS Demo

This section describes how to build the demo described immediately above. The section that follows after describes how to use the Xilinx SDK to create and build a FreeRTOS project.

Importing the demo application project into the SDK Eclipse workspace

To import the Xilinx Software Development Kit (SDK) projects into an existing or new Eclipse Workspace:

  1. Select "Import" from the SDK "File" menu. The dialogue box shown below will appear. Select General->Existing Project into Workspace, as shown in the image.

    Importing the Xilinx MicroBlaze RTOS demo project into the SDK
    The dialogue box that appears when "Import" is first clicked


  2. In the next dialogue box, select FreeRTOS/Demo/CORTEX_A53_64-bit_UltraScale_MPSoC as the root directory. Then, make sure the RTOSDemo_A53, RTOSDemo_A53_bsp and ZynqMP_ZCU102_hw_platform projects are checked in the "Projects" area, and that the Copy Projects Into Workspace box is not checked, before clicking the Finish button (see the image below for the correct check box states).

    Importing the free ARM Cortex-A53 64-bit RTOS Demo Source project into the Xilinx SDK
    Make sure all three projects are checked, and "Copy projects into workspace" is not checked


  3. Once all three projects have been imported, the project explorer window of the SDK IDE will appear as shown below.

    The ZynqMP_ZCU102_hw_platform and RTOSDemo_A53_bsp projects are dependencies of the RTOSDemo_A53 project, so only the RTOSDemo_A53 project needs to be built explicitly.

    The ARM Cortex-A53 RTOS projects viewed in the Eclipse project explorer.
    All three projects imported into the workspace


Building the demo application

  1. Open the project's main.c file, and set mainSELECTED_APPLICATION to generate the simple blinky demo, or the full test and demo application, as required.

  2. Select 'Rebuild All' from the Eclipse IDE 'Project' menu.


Starting a debug session

  1. Ensure the ZCU102 evaluation board is powered up and connected to the host computer using an appropriate debug interface.

  2. Ensure all four switches on bank SW6 are set such that they are toward the centre of the board. This enables JTAG booting.

  3. Select 'Debug Configurations...' from the IDE's 'Run' menu. The Debug Configurations dialogue box will appear. Double click 'Xilinx C/C++ application (System Debugger)' to create a new debug configuration.

  4. Configure the 'Target Setup' tab as shown in the image below.

    64-bit ARM Cortex-A53 target setup tab
    The required settings on the Target Setup tab


  5. Configure the 'Application' tab as shown in the image below.

    64-bit ARM Cortex-A53 RTOS application tab
    The required settings on the Application tab


    All the other tabs in the 'Debug Configurations' dialogue can be left with their default settings.

  6. Click the "Debug" button to commence debugging. The application will be downloaded to RAM and the debugger will break on entry to main(). It may be necessary to select the correct ARM Cortex-A53 core in the Debug window in order to see the correct source code, and use the debugging controls.

    Selecting the ARM Cortex-A53 core in order to debug the RTOS project
    Selecting the ARM Cortex-A53 #0 core in the debug window



Build Instructions - Creating a Basic Project Using the SDK

The previous section described how to build the official FreeRTOS project that comes in the main FreeRTOS zip file download. FreeRTOS also ships with the Xilinx SDK. This section describes how to create a FreeRTOS project using the SDK.

Creating a new FreeRTOS project

  1. Select "New->Application Project" from the SDK "File" menu. The New Project dialogue box will appear.

    Creating a new RTOS project
    Selecting the New Application Project menu item


  2. In the New Project dialogue box, first select "psu_cortexa53_0" as the processor, then select the hardware platform as appropriate, and finally select freertos as the OS platform before clicking "Next". The New Project Templates dialogue will appear.

    The required New Project settings to create a Cortex-A53 RTOS project
    The required New Project dialogue settings


  3. Select the FreeRTOS Hello World template, then click "Finish". The SDK will create a hardware description project, a BSP project, and an application project. The FreeRTOS source code is built as part of the BSP.

    RTOS template for 64-bit port
    Selecting the FreeRTOS template



Configuring a FreeRTOS BSP

The official FreeRTOS demo uses a standalone BSP, and builds FreeRTOS as part of the application. When this is done FreeRTOS is configured by manually editing the FreeRTOSConfig.h header file.

Projects created by the SDK (as just described) build FreeRTOS as part of the BSP. When this is done the FreeRTOSConfig.h header file is not edited manually, and instead FreeRTOS is configured using a dialogue box within the SDK environment.

  1. Follow the instructions above to have a FreeRTOS Hello World application created by the SDK.

  2. Select "Board Support Package Settings" from the SDK "Xilinx Tools" menu. The Board Support Package Settings dialogue will appear.

  3. Select freertos in the left pane of the Board Support Package Settings dialogue, then use the table in the right pane of the same dialogue to configure FreeRTOS as required.

    Configuring the RTOS in the Xilinx SDK
    Using the Board Support Package Settings dialogue to configure FreeRTOS




RTOS Configuration and Usage Details


FreeRTOS ARM Cortex-A port specific configuration

Attention please!: Refer to the page that provides instruction on using FreeRTOS on ARM Cortex-A embedded processors, paying particular attention to the value and meaning of the configMAX_API_CALL_INTERRUPT_PRIORITY setting, and the special notes regarding using the floating point unit with GCC.

Configuration items specific to this demo are contained in /FreeRTOS/Demo/CORTEX_A53_64-bit_UltraScale_MPSoC/RTOSDemo_A53/src/FreeRTOSConfig.h. The constants defined in this file can be edited to suit your application.


Interrupt vector table

By default, SDK projects define the interrupt vector table as part of the BSP. This makes it difficult to install the FreeRTOS handlers using the methods described on the page about running FreeRTOS on ARM Cortex-A embedded processors. Therefore, this demo defines its own interrupt vector table in FreeRTOS_asm_vectors.S. The vector table defined by the BSP is automatically replaced by the vector table defined in FreeRTOS_asm_vectors.S when the scheduler is started.


[Application Defined] Interrupt service routines

Unlike when running the RTOS on the Zynq 7000, you cannot re-enable interrupts in the ARM Cortex-A53 port until after the source of the interrupt has been cleared.

This demo uses drivers provided by Xilinx to configure the interrupt controller, and install application defined interrupts. Examples can be found in FreeRTOS/Demo/CORTEX_A53_64-bit_UltraScale_MPSoC/RTOSDemo_A53/src/Full_Demo/IntQueueTimer.c, which implements and installs the interrupt service routines used by the interrupt nesting test.

The Xilinx drivers require interrupt service routines (ISRs) to accept a void * parameter, although the parameter is not always used. The required ISR prototype is therefore:

    void Interrupt_Handler( void *pvUnusedParameter );
If an ISR causes a task of equal or higher priority than the currently executing task to leave the Blocked state then the ISR must request a context switch before the ISR exits. When this is done the interrupt will interrupt one RTOS task, but return to a different RTOS task.

The macros portYIELD_FROM_ISR() (or portEND_SWITCHING_ISR()) can be used to request a context switch from within an ISR. The following source code snippet is provided as an example. The example ISR uses a direct to task notification to synchronise with a task (not shown), and calls portYIELD_FROM_ISR() to ensure the interrupt returns directly to the task.

void Dummy_IRQHandler( void *pvUnusedInThisExample )
{
long lHigherPriorityTaskWoken = pdFALSE;

    /* The parameter is not used in this case. */
    ( void ) pvUnusedInThisExample;

    /* Clear the interrupt if necessary. */
    Dummy_ClearITPendingBit();

    /* This interrupt does nothing more than demonstrate how to synchronise a
    task with an interrupt.  A direct to task notification is used for this
    purpose.  Note lHigherPriorityTaskWoken is initialised to pdFALSE. */
    vTaskNotifyGiveFromISR( xTaskToNotify, &lHigherPriorityTaskWoken );

    /* If the task referenced by xTaskToNotify was blocked waiting for the
    notification, and sending the notification caused the task to unblock, and
    the unblocked task has a priority higher than or equal to the currently
    Running task (the task that this interrupt interrupted), then
    lHigherPriorityTaskWoken will have been set to pdTRUE internally within
    vTaskNotifyGiveFromISR().  Passing pdTRUE into the portYIELD_FROM_ISR() macro
    will result in a context switch being pended to ensure this interrupt returns
    directly to the unblocked, higher priority, task.  Passing pdFALSE into
    portYIELD_FROM_ISR() has no effect. */
    portYIELD_FROM_ISR( lHigherPriorityTaskWoken );
}

Only FreeRTOS API functions that end in "FromISR" can be called from an interrupt service routine - and then only if the priority of the interrupt is less than or equal to that set by the configMAX_API_CALL_INTERRUPT_PRIORITY configuration constant (meaning a numerically higher value).


Resources used by FreeRTOS

Information is provided on the Using FreeRTOS on ARM Cortex-A Embedded Processors page. This demo is configured to generate the tick interrupt from a TTT channel.


Memory allocation

The FreeRTOSConfig.h header file used by the demo has both configSUPPORT_STATIC_ALLOCATION and configSUPPORT_DYNAMIC_ALLOCATION defined, and the demo shows both methods being used. Source/Portable/MemMang/heap_4.c is included in the 64-bit ARM Cortex-A53 demo application project to provide the memory allocation required when objects are created using dynamic memory allocation. Please refer to the Memory Management section of the API documentation for full information.


Miscellaneous

Note that vPortEndScheduler() has not been implemented.






Copyright (C) Amazon Web Services, Inc. or its affiliates. All rights reserved.