TI AM243x LaunchPad

Overview

The AM243x Launchpad is a development board that is based of a AM2434 SoC and therefor has two dualcore Cortex-R5F clusters running at 800 MHz and a Cortex-M4F running at 400 MHz. The board also includes a flash chip, DIP-Switches for the boot mode selection and 2 RJ45 Ethernet ports.

More information can be found at the AM243x Launchpad product page [5] and the AM2434 SoC website [6].

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 Launchpad

The AM243x Launchpad uses an AM2434 SoC resulting in 2 dualcore Cortex-R4F clusters running at 800 MHz in the MAIN domain and a Cortex-M4F running at 400 MHz in the MCU domain.

The board physically contains:

  • 512 Mb (equal to 64 MB) of Infineon NOR Flash

  • DIP switches to change the boot mode

  • Buttons for different reset methods

  • Multiple LEDs (some for power indication and some connected to GPIO pins)

  • Two physical Ethernet ports including PHYs

  • A XDS110 debug probe (JTAG emulation)

The Cortex-R5F0_0 core uses the UART peripheral connected to the XDS110 debug probe by default and is therefor usable without additional UART to USB bridge. The Cortex-M4F core uses the MCU_UART0 peripheral by default to avoid conflicts which is accessible via the J17 header on the board.

Supported Features

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

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

SW4 [1:7]

11100000

QSPI Boot Mode

SW4 [1:7]

01000100

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-lp (or set it as environment variable, if it is not inside a file)!

Note

Please be aware that while this board using Quad SPI (QSPI) instead of Octal SPI (OSPI) the TI MCU+ SDK still uses QSPI correctly inside the OSPI code for this board

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 lp_am243/<soc>/<core> <my_app>
west debug

Hint

To utilize this feature, you’ll need an OpenOCD version that is new enough and therefor might need to compile OpenOCD yourself. You can look at building OpenOCD from source [7] for documentation on how to do that.

References