The NXP/Freescale VF6xx SoC which is the core of the Colibri VF61 module implements a heterogeneous asymmetric architecture. Besides the main CPU core based on the ARM Cortex-A5 processor, a secondary general purpose ARM Cortex-M4 core is available too. The secondary core typically runs a RTOS optimized for microcontrollers or a bare-metal application. Toradex provides FreeRTOS™, a free professional grade real-time operating system for microcontrollers, along with drivers and several examples which can be used on our Colibri VF61 platform. The FreeRTOS™ port is based on NXP FreeRTOS BSP for i.MX 7.

The Cortex-M4 CPU core lives side by side with the Cortex-A5 based primary CPU core. Both CPU complexes have access to the same interconnect and hence have equally access to all peripherals (shared bus topology).

There are several types of memory available. The Cortex-M4 provides local memory (Tightly Coupled Memory, TCM), which is relatively small but can be accessed by the CPU without any latency. There are multiple OCRAM areas (On-Chip RAM, typically SRAM) which are relatively fast as well and slightly larger. The third option is the DDR3 based main memory. From a performance perspective one of the internal areas should be selected whenever possible.

A traditional microcontroller typically has internal NOR flash where the firmware is stored and executed from. This is not the case on Colibri VF61: There is no NOR flash where the firmware can be flashed onto. Instead, the firmware needs to be stored on the mass storage device such as SD-card or the internal NAND flash. The available mass storage devices are not "memory mapped", and hence application can not be executed directly from any of the cores (no eXecuted-In-Place, XIP). Instead, code need to be loaded into one of the available memory sections before the CPU can start executing it.

The Colibri VF61 always boots using the Cortex-A5 core. The core executes the internal boot ROM which typically loads a boot loader such as U-Boot. The boot loader allows loading the firmware from the mass storage device (e.g. NAND flash) into memory, and triggers the Cortex-M4 to start executing the firmware. To upgrade or replace a firmware, one can just replace the firmware binary on the mass storage device.

The two CPU platforms use a different memory layout to access individual sub systems. This table lists some important areas and their memory location for each of the cores side by side. The full list can be found in the Vybrid reference manual.

Each example has a sub-directory called armgcc. Enter this subdirectory and use the provided shell scripts to build the example. The scripts expect the environment variable to point to the Linaro ARM Embedded toolchain:

Note:
In release image 2.7 Beta1, support for m4boot has been dropped from u-boot and remoteproc is the only method to boot and run firmware on Cortex-M4.
In release image 2.7 Beta2, support for bootaux has been added including elf boot support.

Note:
The FreeRTOS firmware uses Colibri UART_B as its debugging console. Make sure to connect UART_B to your debugging host and start a serial terminal emulator with a baud rate of 115200 on the serial port.

Linux disables unused clocks by default but it is not aware what clocks are used by the Cortex-M4 core. Use the 'clk_ignore_unused' kernel parameter to avoid clocks getting accidentally disabled. The power management suspend code and the Cortex-M4 firmware typically use the same SRAM location leading to a resource conflict. To prevent the suspend code from overwriting the M4 firmware and/or remoteproc from not being able to load, the SRAM driver should be disabled by passing 'initcall_blacklist=sram_init' kernel parameter:

By default, our Linux device tree uses UART_B too, which leads to a external abort when the Linux kernel tries to access UART_B. It is recommended to alter the device tree and disable UART_B using the status property (see Device Tree Customization(901439e4-9c90-11e4-8c91-9e9dd95319f8)). Temporary, the following fdt_fixup command can be use in U-Boot:

Use the following commands to create a UBI volume to store the Cortex-M4 firmware (to free up space for this volume this process will remove the rootfs volume!). The update scripts are required for this steps, make sure you have a SD-card with the image prepared and in your SD-card slot.

In images using U-Boot 2015.04 (BSPs before 2.7), one need to use FIT image to boot Cortex-M4 from U-Boot via m4boot.

Creating FIT image:

Use the image source file(.its) which describes the contents of the image(the actual binary is specified in the form of path and various properties used during booting). One need to also make sure to add the relevant 'entry' address in the image source file. The entry address will be the entry point address of the binary, one can get the information using readelf.

In our release image (since v2.6.1), by default remoteproc is disabled to allow Cortex-M4 to start from U-Boot. To start Cortex-M4 using remoteproc, deploy the .elf to '/lib/firmware' directory and load the remoteproc kernel modules. To auto load the remoteproc driver during boot, manually add vf610_cm4_rproc.conf file in '/etc/modules-load.d/'
with the remoteproc driver vf610_cm4_rproc specified in the conf file.

This section provides information about the available examples and how to use them. The source code of the Colibri VF61 examples are located under examples/vf6xx_colibri_m4/. All examples are linked to run in the SRAM area.

GPIO example using input and output. Example uses SO-DIMM_PIN: for button/key and SO-DIMM_PIN: for a LED. On a Colibri Evaluation board, you can use header X9 to connect the SO-DIMM signals to a button or LED respectively:

This example uses the messaging mechanism to send an integer value back and forth, while incrementing it on both sites. The demo will stop after 1000 iterations (that is when 2000 incrementations have been executed).

Configure ExecuteAddr, the entry point instruction of the firmware. Please refer Memory Map section for more details.

Configure RxRingAddr, Rx shared memory address. This must be identical to the "VRING0_BASE" value in the file "\freertos-toradex\middleware\multicore\open-amp\porting\vf6xx_m4\platform_info.c".

Configure TxRingAddr, Tx shared memory address. This must be identical to the "VRING1_BASE" value in the file "\freertos-toradex\middleware\multicore\open-amp\porting\vf6xx_m4\platform_info.c".

Configure ChannelName, communication channel name to filter the packets. This must be identical to the configured channel name in proc_table structure in "\freertos-toradex\middleware\multicore\open-amp\porting\vf6xx_m4\platform_info.c".

Call Rpmsg_Open to initialize the firmware.

Get name of the event using DataAvailableEvent for creating an event and wait till you receive any message.

Flush the message buffer by calling FlushRcvFifo and start transmitting and receiving data.