TI AM243x-EVM

Overview

The AM243x EVM is a development board that is based of a AM2434 SoC. The Cortex R5F cores in the SoC run at 800 MHz. The board also includes a flash region, DIP-Switches for the boot mode selection and 2 RJ45 Ethernet ports.

See the TI TMDS243EVM Product Page [6] or its technical reference manual [5] for details.

Hardware

AM64x/AM243x features

The AM64x / AM243x is a SoC series that supports up to 2 Cortex-A53 cores (only in AM64x SoCs) running with typically 1 GHz, up to 4 Cortex-R5F cores running with typically 800 MHz and one Cortex-M4F core running with typically 400 MHz. Inside Zephyr code both series are referenced as AM64x since they only differ in whether Cortex-A cores are present. If you use an AM243x series SoC everything related to Cortex-A cores doesn’t apply to you. These things are sometimes still documented due to shared documentation files.

The ARM cores and peripherals are separated into the MAIN and MCU domain whereby only the ARM Cortex-M4F core is inside the MCU domain. By default both domains can interact with each other but it is also possible to isolate both domains.

A non-exhaustive overview can be found in the following listing. Not all peripherals are supported inside Zephyr as of now:

  • Up to 2 ARM Cortex-A53 cores

  • Up to 2 dualcore Cortex-R5F clusters

  • 1x Cortex-M4F

  • 2 MiB internal SRAM

  • GPIO

  • ADC

  • UART

  • SPI

  • I2C

  • Multiple Timers

  • Multiple Watchdogs

  • CAN-FD

  • Ethernet

  • USB

  • PCIe

  • External (LP)DDR4 RAM interface

  • DMSC (centralized power / resource management)

  • Crypto acceleration

  • Secureboot

The AM243x-EVM board

This development board specifically uses an AM2434 SoC resulting in 4 Cortex-R5F cores and a Cortex-M4F core. These Cortex-R5F cores run at 800 MHz and the Cortex-M4F core runs at 400 MHz.

On the board it additionally features

  • 2GB DDR4 RAM

  • XDS110 based JTAG

Inside Zephyr it configures

  • a 4KB Resource Table at 0xa4100000 for the M4

  • a 4KB Resource Table at 0xa0100000 for the R5F0_0

  • 8MB of Shared Memory at 0xa5000000 for inter-processor communication

  • MAIN domain UART0 for the R5F0_0

  • MCU domain UART0 (MCU_UART0) for the M4

Supported Features

The am243x_evm board supports the hardware features listed below.

on-chip / on-board
Feature integrated in the SoC / present on the board.
2 / 2
Number of instances that are enabled / disabled.
Click on the label to see the first instance of this feature in the board/SoC DTS files.
vnd,foo
Compatible string for the Devicetree binding matching the feature.
Click on the link to view the binding documentation.

am243x_evm/am2434/m4 target

Type

Location

Description

Compatible

CPU

on-chip

ARM Cortex-M4F CPU1

arm,cortex-m4f

ADC

on-chip

TI AM335X ADC1

ti,am335x-adc

Clock control

on-chip

Generic fixed-rate clock provider1

fixed-clock

Firmware

on-chip

TISCI Client Driver1

ti,k2g-sci

GPIO & Headers

on-chip

GPIO Controller for Davinci and Keystone devices2

ti,davinci-gpio-nexus

on-chip

GPIO Controller for Davinci and Keystone devices16

ti,davinci-gpio

I2C

on-chip

TI OMAP I2C Controller6

ti,omap-i2c

Interrupt controller

on-chip

ARMv7-M NVIC (Nested Vectored Interrupt Controller)1

arm,v7m-nvic

LED

on-board

Group of GPIO-controlled LEDs1

gpio-leds

Mailbox

on-chip

TI Secure Proxy MAILBOX1

ti,secure-proxy

on-chip

TI OMAP MAILBOX17

ti,omap-mailbox

Pin control

on-chip

TI K3 Pin Controller11

ti,k3-pinctrl

Power domain

on-chip

TISCI-managed power domain148

ti,sci-pm-domain

Serial controller

on-chip

ns16550 UART18

ns16550

SPI

on-chip

TI Multi Channel SPI controller for OMAP and K3 SoCs7

ti,omap-mcspi

SRAM

on-chip

Generic on-chip SRAM2

mmio-sram

System controller

on-chip

TI-K3 device level control register module2

ti,control-module

Timer

on-chip

ARMv7-M System Tick1

arm,armv7m-systick

on-chip

TI Dual-Mode Timer12

ti,am654-timer

Watchdog

on-chip

K3 Watchdog timer (RTI module) available in the K3 generation of processors16

ti,j7-rti-wdt

am243x_evm/am2434/r5f0_0 target

Type

Location

Description

Compatible

CPU

on-chip

ARM Cortex-R5F CPU1

arm,cortex-r5f

ADC

on-chip

TI AM335X ADC1

ti,am335x-adc

Firmware

on-chip

TISCI Client Driver1

ti,k2g-sci

GPIO & Headers

on-chip

GPIO Controller for Davinci and Keystone devices2

ti,davinci-gpio-nexus

on-chip

GPIO Controller for Davinci and Keystone devices16

ti,davinci-gpio

I2C

on-chip

TI OMAP I2C Controller15

ti,omap-i2c

Interrupt controller

on-chip

TI Vectored Interrupt Manager is a external interrupt controller (TI specific IP) which is compatible with R5F VIC port1

ti,vim

LED

on-board

Group of GPIO-controlled LEDs1

gpio-leds

Mailbox

on-chip

TI Secure Proxy MAILBOX1

ti,secure-proxy

on-chip

TI OMAP MAILBOX26

ti,omap-mailbox

Pin control

on-chip

TI K3 Pin Controller2

ti,k3-pinctrl

Power domain

on-chip

TISCI-managed power domain148

ti,sci-pm-domain

Serial controller

on-chip

ns16550 UART18

ns16550

SPI

on-chip

TI Multi Channel SPI controller for OMAP and K3 SoCs16

ti,omap-mcspi

System controller

on-chip

TI-K3 device level control register module2

ti,control-module

Timer

on-chip

TI Dual-Mode Timer111

ti,am654-timer

Watchdog

on-chip

K3 Watchdog timer (RTI module) available in the K3 generation of processors16

ti,j7-rti-wdt

Booting a firmware

The AM64x/AM243x bootflow

The AM64x/AM243x SoC series has it’s own bootflow due to supporting secure boot. After powering on the SoC an immutable bootloader in ROM (called RBL) is executed on R5F0_0. Based on the MCU+ SDK from Texas Instruments then a Second Stage Bootloader (called SBL) should be executed which then boots the final Zephyr firmware. The RBL can get it’s image from various sources, such as external flash or transmitted via UART. An alternative only on AM64x series SoCs it to use a premade image from a TI SDK that acts as SBL, starts Linux on the Cortex-A and then use remoteproc to load a Zephyr firmware onto another core.

On this board the location from which the SBL image is fetched can be selected with the DIP switches.

UART Boot Mode

SW2 [0:7]

SW3 [8:15]

11011100

10110000

OSPI Boot Mode

SW2 [0:7]

SW3 [8:15]

11001110

01000000

Flashing

The boot process of the AM2434 SoC requires the booting image to be in a specific format and to wait for the internal DMSC-L of the AM2434 to start up and configure memory firewalls. Since there exists no Zephyr support it’s required to use one of the SBL bootloader examples from the TI MCU+ SDK.

Attention

For all MCU+ SDK related sections you need to replace $Z_MCUPSDK_BOARD with am243x-evm (or set it as environment variable, if it is inside a file)!

MCU+ SDK

Setup

The following steps are from the time this documentation was written and might change in the future. They target Linux with assumption some basic things (like python3 and openssl) are installed.

To build these you need to install the TI MCU+ SDK. To do this you need to follow the steps described in the mcupsdk-core Github repository [4], which includes cloning the repositories with west. It’s recommended to use another Python venv for this since the MCU+ SDK has own Python dependencies that could conflict with Zephyr dependencies. You can replace all/dev.yml in the west init command with am243x/dev.yml, if you want to clone a few less repositories.

You also need to follow the “Downloading And Installing Dependencies” section but you need to replace all am263x occurrences in commands with am243x. You can pass --skip_doxygen=true and --skip_ccs=true to the install script, if you don’t want them. You might encounter a error that a script can’t be executed. To fix it you need to mark it as executable with chmod +x <path> and run the download_components.sh again.

Attention

Please also take note of the tools and mcu_plus_sdk install path. The tools install path (from download_components.sh) will later be referred to as $TI_TOOLS and the MCU+ SDK path (The mcu_plus_sdk directory from where you ran west init) as $MCUPSDK. It is recommended to set them as environment variables but it’s still necessary to replace them accordingly inside files.

Note

Summarized you will most likely want to run the following commands or similar versions for setting up the MCU+ SDK:

python3 -m venv .venv
source .venv/bin/activate
pip3 install west
west init -m https://github.com/TexasInstruments/mcupsdk-manifests.git --mr mcupsdk_west --mf am243x/dev.yml
west update
./mcupsdk_setup/am243x/download_components.sh --skip_doxygen=true --skip_ccs=true

After the script finished successfully you want to switch into $MCUPSDK and edit the source/drivers/bootloader/bootloader.c file to set the entryPoint to 0 inside Bootloader_runCpu unconditionally. This is needed due to how Zephyr builds the image currently.

Now you can build the internal libraries with the following commands:

make gen-buildfiles DEVICE=am243x PROFILE=release
make libs DEVICE=am243x PROFILE=release

If you encounter compile errors you have to fix them. For that you might have to change parameter types, remove missing source files from makefiles or download missing headers from the TI online reference.

Building MCU+ SDK SBLs

The example SBL implementations are found in the examples/drivers/boot/<example>/$Z_MCUPSDK_BOARD/r5fss0-0_nortos directory.

You can build the example by invoking make -C examples/drivers/boot/<example>/$Z_MCUPSDK_BOARD/r5fss0-0_nortos/ti-arm-clang/ DEVICE=am243x PROFILE=release from the $MCUPSDK directory. While there exists a sbl_prebuilt directory it has no contents as of now and is only populated during the SBL build itself.

Depending on your usage it is recommended to build the following SBLs as necessary:

sbl_null

Bootloader to load a Zephyr .elf directly via the Code Composer Studio IDE. Recommended to be booted from flash and during development due to ease of use.

sbl_uart

Bootloader to boot a firmware in RPRC format file via UART. Recommended to be booted from UART and during development due to not having to switch the bootmode between UART and OSPI all the time.

sbl_ospi

Bootloader to load a firmware in RPRC format from flash. Recommended, if persistence is required. It looks for a RPRC image at flash offset 0x80000.

sbl_uart_uniflash

Application that can be booted after the RBL. Usually loaded via UART. Receives data via UART and writes them to flash.

You can find more SBLs on the TI MCU+ SDK bootflow documentation website [1].

Flashing data into external flash with the MCU+ SDK

To flash data onto external flash you want to build the sbl_uart_uniflash example, copy the built file called sbl_uart_uniflash.release.hs_fs.tiimage into your working directory and create a config file, replacing $FLASH_OFFSET and $FLASH_FILE with the offset on the flash and file you want to flash.

Note

$FLASH_OFFSET should be given as hexadecimal address like 0x80000

Note

It is possible to flash multiple files into different locations without rebooting. All that is needed to do is copy the last line and andjust the file and flash offset.

--flash-writer=sbl_uart_uniflash.release.hs_fs.tiimage
--operation=flash-phy-tuning-data
--file=$FLASH_FILE --operation=flash --flash-offset=$FLASH_OFFSET

After that you need to run python3 uart_uniflash.py -p /dev/ttyUSB0 --cfg=<path-to-the-config-file>. You might have to adjust /dev/ttyUSB0 depending on your connected devices. You can find more documentation on the TI MCU+ SDK flashing documentation website [2].

Creating a SBL bootable RPRC image from a Zephyr ELF

To convert a Zephyr ELF file into a RPRC file that can be booted by a SBL like sbl_uart or sbl_ospi you need to run multiple commands. They are given in the below code block and under the assumption that the zephyr.elf file is in the current working directory. Based the core you want to run the firmware on you can change BOOTIMAGE_CORE_ID.

export BOOTIMAGE_CORE_ID_r5fss0-0=4
export BOOTIMAGE_CORE_ID_m4=14
# set CORE_ID as per your target core
export BOOTIMAGE_CORE_ID=${BOOTIMAGE_CORE_ID_desired-core}
$TI_TOOLS/sysconfig_1.21.2/nodejs/node $MCUPSDK/tools/boot/out2rprc/elf2rprc.js ./zephyr.elf
$MCUPSDK/tools/boot/xipGen/xipGen.out -i ./zephyr.rprc -o ./zephyr.rprc_out -x ./zephyr.rprc_out_xip --flash-start-addr 0x60000000
$TI_TOOLS/sysconfig_1.21.2/nodejs/node $MCUPSDK/tools/boot/multicoreImageGen/multicoreImageGen.js --devID 55 --out ./zephyr.appimage ./zephyr.rprc_out@${BOOTIMAGE_CORE_ID}
$TI_TOOLS/sysconfig_1.21.2/nodejs/node $MCUPSDK/tools/boot/multicoreImageGen/multicoreImageGen.js --devID 55 --out ./zephyr.appimage_xip ./zephyr.rprc_out_xip@${BOOTIMAGE_CORE_ID}
python3 $MCUPSDK/source/security/security_common/tools/boot/signing/appimage_x509_cert_gen.py --bin ./zephyr.appimage --authtype 1 --key $MCUPSDK/source/security/security_common/tools/boot/signing/app_degenerateKey.pem --output ./zephyr.appimage.hs_fs

The resulting file will be zephyr.appimage.hs_fs in the current working directory. It is in the TI RPRC format that is understood by SBLs. The format is described on the TI MCU+ SDK boot tools documentation website [3].

Full bootflow examples

As summary which steps are required for a boot are listed here.

To boot via the debuuger you first should build sbl_uart_uniflash and sbl_null as described in Building MCU+ SDK SBLs. After that you should put your board into the UART boot mode and flash the sbl_null.release.hs_fs.tiimage file to address 0x0 as described in Flashing data into external flash with the MCU+ SDK.

After that you can switch into OSPI boot mode and load Zephyr ELF files directly via the Code Composer Studio debugger onto the core you want.

Debugging

OpenOCD

The board is equipped with an XDS110 JTAG debugger. To debug a binary, utilize the debug build target:

west build -b am243x_evm/<soc>/<core> <my_app>
west debug

Hint

To utilize this feature, you’ll need OpenOCD version 0.12 or higher. Due to the possibility of older versions being available in package feeds, it’s advisable to build OpenOCD from source [7].

References