Port and integrate FreeRTOS on the Arm Zena CSS Safety Island
Introduction
Build the Cortex-R82 FreeRTOS demo
Build and validate FreeRTOS on the Cortex-R82AE FVP
Load FreeRTOS directly into Zena CSS Safety Island Cluster 1
Add FreeRTOS to the Zena CSS software stack boot flow
Integrate FreeRTOS into Zena CSS with Yocto
Next Steps
Port and integrate FreeRTOS on the Arm Zena CSS Safety Island
Run FreeRTOS in the Zena CSS software stack
You’ve validated FreeRTOS by loading the image directly on the Zena Fixed Virtual Platform (FVP).
Now, you’ll validate the application in the complete Zena CSS software stack by replacing the default Zephyr Cluster 1 firmware with a FreeRTOS image.
You’ll use a manually substituted binary for this validation.
Before you begin
Ensure that the following environment is ready:
- A working Zena CSS build environment
- A working Zena CSS Configuration 2 FVP platform
- A FreeRTOS binary built for the
zena-csstarget
Build the FreeRTOS image
To build the FreeRTOS image, complete the following steps.
Update the GIC configuration for view 2
The direct-loading workflow used during bring-up doesn’t follow the normal Zena CSS boot sequence. In that environment, the System Control Processor (SCP) firmware isn’t running. The Generic Interrupt Controller (GIC) remains in its default configuration.
The initial FreeRTOS port therefore uses GIC view 0 to simplify platform bring-up and debugging.
In the standard Zena CSS boot process, SCP firmware configures the GIC multi-view topology before releasing the Safety Island software. Safety Island Cluster 1 is assigned to GIC view 2, which is the same view that’s used by the default Zephyr RTOS.
To replace the Cluster 1 Zephyr image, FreeRTOS has to use the same GIC view and redistributor addresses as the original firmware. Otherwise, interrupt configuration no longer matches the platform state.
For more information, see GIC multiple views in the Arm Zena CSS documentation .
The published demo already defines both configurations. Selecting zena_css_fvp configures the GIC distributor and redistributor base addresses for GIC view 2 in FreeRTOSConfig.h:
#elif defined( R82AE_PLATFORM_ZENA_CSS_FVP )
#define configGIC_SGI_CORE_AFFINITY_LEVEL 1U
#define configINTERRUPT_CONTROLLER_BASE_ADDRESS 0x30200000UL
#define configGIC_REDISTRIBUTOR_BASE_ADDRESS 0x30260000UL
#define configINTERRUPT_PRIORITY_REGISTER_ADDRESS ( configGIC_REDISTRIBUTOR_BASE_ADDRESS + 0x10400UL )
#define configPL011_UART0_BASE_ADDRESS 0x2A410000UL
#define configGIC_SGI_AFF2 1U
#define configGENERIC_TIMER_INTERRUPT_ID 29UL
Compile the application
Build with either GCC or Arm Compiler for Embedded and configure the exact full-stack platform target, zena_css_fvp:
cd $HOME
cd FreeRTOS-Partner-Supported-Demos/CORTEX_R82AE_SMP_FVP_MPU_GCC_ARMCLANG
cmake -S . -B build/zena_css \
-DCMAKE_TOOLCHAIN_FILE=gnu_toolchain.cmake \
-DCMAKE_BUILD_TYPE=Debug \
-DKERNEL_DIR_PATH=../../FreeRTOS-Kernel \
-DR82AE_PLATFORM=zena_css_fvp
cmake --build build/zena_css --parallel
aarch64-none-elf-objcopy -O binary \
build/zena_css/r82ae_smp_fvp_gcc_armclang.elf \
build/zena_css/r82ae_smp_fvp_gcc_armclang.bin
The generated binary is located at build/zena_css/r82ae_smp_fvp_gcc_armclang.bin.
Record the full path to this file.
Understand how the firmware is packaged
If you’re familiar with the Zena CSS firmware packaging flow, continue to Replace the Cluster 1 firmware .
Before replacing the Cluster 1 firmware, trace how it’s packaged into the final Zena CSS image. Use this investigation process when integrating software into other Yocto-based platforms.
Review the Zena CSS software architecture
Before examining the Yocto build system, review the Zena CSS architecture. Identify the software running on each processing element.
The following components are important:
- Runtime Security Engine (RSE)
- SCP
- Application Processing (AP) subsystem
- Safety Island Cluster 1 (SI CL1)
By default, SI CL1 runs a Zephyr image.
You’ll replace the SI CL1 Zephyr image with a FreeRTOS image while leaving all other software components unchanged.
Safety Island CL1 firmware loading
The Zena CSS documentation indicates that the SI CL1 firmware is loaded by the Zena CSS RSE boot flow .
The Zena CSS RSE image layout indicates where the SI CL1 image is packaged.
The SI CL1 image in rse-flash-image.img is signed, so replacing the image within the binary isn’t sufficient.
Locate the recipe responsible for the RSE image
Because the Zephyr image is packaged in rse-flash-image.img, search for recipes related to firmware image generation.
From the arm-zena-css directory, using $ZENA_YOCTO_DIR as the starting point, find the RSE image definition:
cd $ZENA_YOCTO_DIR/arm-zena-css
grep -nr "rse-flash-image" yocto/
The search identifies
firmware.cfg
.
The output is similar to:
./arm-zena-css/yocto/meta-zena-css-bsp/recipes-bsp/images/files/fvp-rd-aspen/firmware.cfg
yocto/meta-zena-css-bsp/recipes-bsp/images/files/fvp-rd-aspen/firmware.cfg:31:image rse-flash-image.img {
Find the recipe that uses this configuration:
grep -nr "firmware.cfg" yocto/
The search links this configuration to the image recipe.
The output is similar to:
yocto/meta-zena-css-bsp/recipes-bsp/images/firmware-fvp-rd-aspen.bb:40:GENIMAGE_CONFIG = "firmware.cfg"
This establishes the link between the image definition and the recipe that generates it.
Open firmware-fvp-rd-aspen.bb and inspect its tasks. You’ll modify this recipe to replace the default Cluster 1 firmware with the FreeRTOS image while preserving the normal Zena CSS boot flow.
Identify where the SI CL1 firmware enters the image
The objective is to determine where the Zephyr SI CL1 firmware is added to the image packaging flow.
Because the target component is SI CL1, search the recipe for terms such as cl1 and safety_island.
Inside the image-signing logic you will find commands similar to:
cp ${RECIPE_SYSROOT}/firmware/${SI_CL1_FIRMWARE_BINARY} \
${B}/safety_island_cl1.bin
This is the point where the default SI CL1 firmware enters the image packaging workflow.
Choose the fastest validation strategy
A production integration would provide FreeRTOS through its own Yocto recipe. However, this adds complexity to source management, recipe maintenance, dependency tracking, and build integration.
For an initial platform validation, none of that is required.
The FreeRTOS binary has already been built externally:
cd $HOME
pwd
find . -name r82ae_smp_fvp_gcc_armclang.bin -print | grep -i zena_css
This example uses /home/bob for $HOME. The output is similar to:
/home/bob
./FreeRTOS-Partner-Supported-Demos/CORTEX_R82AE_SMP_FVP_MPU_GCC_ARMCLANG/build/zena_css/r82ae_smp_fvp_gcc_armclang.bin
The quickest way to validate functionality is to replace the SI CL1 payload at the image-packaging stage.
This approach keeps the existing Zena CSS build flow unchanged while allowing the FreeRTOS image to pass through the normal signing and boot process.
Replace the Cluster 1 firmware
Open the file $HOME/arm-auto-solutions/arm-zena-css/yocto/meta-zena-css-bsp/recipes-bsp/images/firmware-fvp-rd-aspen.bb.
Locate the following command in the do_sign_images() function:
cp ${RECIPE_SYSROOT}/firmware/${SI_CL1_FIRMWARE_BINARY} \
${B}/safety_island_cl1.bin
Replace it with the full path to the r82ae_smp_fvp_gcc_armclang.bin binary. The following example uses /home/bob for $HOME:
cp /home/bob/FreeRTOS-Partner-Supported-Demos/CORTEX_R82AE_SMP_FVP_MPU_GCC_ARMCLANG/build/zena_css/r82ae_smp_fvp_gcc_armclang.bin \
${B}/safety_island_cl1.bin
This replaces the default Zephyr Cluster 1 firmware while leaving the remainder of the Zena CSS software stack unchanged.
Rebuild the firmware image
Create a new tmux session:
cd $HOME/arm-auto-solutions
tmux new-session -s arm-auto-solutions
From the new tmux session, force regeneration of the signed images:
kas shell -c 'bitbake firmware-fvp-rd-aspen -C sign_images'
Build the updated firmware package:
kas build --target firmware-fvp-rd-aspen
Locate the generated flash image:
find . -name rse-flash-image.img -print
The output is similar to:
./build/tmp_baremetal/deploy/images/fvp-rd-aspen/rse-flash-image.img
Boot the platform
Launch the Zena CSS FVP in a tmux session:
kas shell -c '../layers/meta-arm/scripts/runfvp -t tmux'
Wait for the platform to complete boot. Press Ctrl-b, then w. Then, select SI C1 - terminal_uart_si_cluster1.
At the > prompt, enter ping:
> ping
The expected output is:
Ping from Core 0
Pong response from Core 1
Pang response from Core 2
Pung response from Core 3
A successful run supports the following conclusions:
- The FreeRTOS image was authenticated and loaded by RSE.
- The image packaging process completed successfully.
- SCP firmware initialized the platform correctly.
- GIC view 2 has been configured by Safety Island CL0 (SCP).
- FreeRTOS can replace Zephyr in the complete Zena CSS software stack.
If you see only SI C0 - terminal_uart_si_cluster0, press Ctrl-b. Then, press d to detach from your current tmux session and return to the Bash shell of the Ubuntu build host.
Stop your tmux processes:
pkill '^tmux'
Next, open the Yocto build menu for Zena CSS:
kas menu arm-zena-css/Kconfig
Select RD-Aspen Cfg2, then select Save and Exit.
Perform an incremental build:
kas build
kas shell -c 'bitbake firmware-fvp-rd-aspen -C sign_images'
kas build --target firmware-fvp-rd-aspen
Launch the FVP again:
kas shell -c "../layers/meta-arm/scripts/runfvp -t tmux --verbose"
Allow the new instance to boot to the login prompt. Press Ctrl-b, then w. Select SI C1 - terminal_uart_si_cluster1 and enter ping at the > prompt.
What you’ve accomplished and what’s next
You’ve validated a FreeRTOS image in the complete Zena CSS software stack.
By manually replacing the default Zephyr Cluster 1 firmware, you verified that the application works correctly with the standard secure boot, image signing, and firmware packaging flow.
Next, you’ll automate this process using Yocto.