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 |
|
ADC |
on-chip |
TI AM335X ADC1 |
|
Clock control |
on-chip |
Generic fixed-rate clock provider1 |
|
Firmware |
on-chip |
TISCI Client Driver1 |
|
GPIO & Headers |
on-chip |
GPIO Controller for Davinci and Keystone devices2 |
|
on-chip |
|||
I2C |
on-chip |
TI OMAP I2C Controller6 |
|
Interrupt controller |
on-chip |
ARMv7-M NVIC (Nested Vectored Interrupt Controller)1 |
|
LED |
on-board |
Group of GPIO-controlled LEDs1 |
|
Mailbox |
on-chip |
TI Secure Proxy MAILBOX1 |
|
on-chip |
|||
Pin control |
on-chip |
||
Power domain |
on-chip |
TISCI-managed power domain148 |
|
Serial controller |
on-chip |
||
SPI |
on-chip |
TI Multi Channel SPI controller for OMAP and K3 SoCs7 |
|
SRAM |
on-chip |
Generic on-chip SRAM2 |
|
System controller |
on-chip |
TI-K3 device level control register module2 |
|
Timer |
on-chip |
ARMv7-M System Tick1 |
|
on-chip |
TI Dual-Mode Timer12 |
||
Watchdog |
on-chip |
K3 Watchdog timer (RTI module) available in the K3 generation of processors16 |
am243x_evm/am2434/r5f0_0 target
Type |
Location |
Description |
Compatible |
|---|---|---|---|
CPU |
on-chip |
ARM Cortex-R5F CPU1 |
|
ADC |
on-chip |
TI AM335X ADC1 |
|
Firmware |
on-chip |
TISCI Client Driver1 |
|
GPIO & Headers |
on-chip |
GPIO Controller for Davinci and Keystone devices2 |
|
on-chip |
|||
I2C |
on-chip |
||
Interrupt controller |
on-chip |
TI Vectored Interrupt Manager is a external interrupt controller (TI specific IP) which is compatible with R5F VIC port1 |
|
LED |
on-board |
Group of GPIO-controlled LEDs1 |
|
Mailbox |
on-chip |
TI Secure Proxy MAILBOX1 |
|
on-chip |
|||
Pin control |
on-chip |
TI K3 Pin Controller2 |
|
Power domain |
on-chip |
TISCI-managed power domain148 |
|
Serial controller |
on-chip |
||
SPI |
on-chip |
||
System controller |
on-chip |
TI-K3 device level control register module2 |
|
Timer |
on-chip |
||
Watchdog |
on-chip |
K3 Watchdog timer (RTI module) available in the K3 generation of processors16 |
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.
SW2 [0:7] |
SW3 [8:15] |
|---|---|
11011100 |
10110000 |
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
.elfdirectly 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.
To boot an image via UART you need to build sbl_uart as described in
Building MCU+ SDK SBLs and switch your board into the UART boot mode.
Then you need to convert the Zephyr ELF file to a RPRC as descrbied in
Creating a SBL bootable RPRC image from a Zephyr ELF and run
python3 $MCUPSDK/tools/boot/uart_bootloader.py -p /dev/ttyUSB0 --bootloader=sbl_uart.release.hs_fs.tiimage --file=zephyr.appimage.hs_fs
To boot an image via OSPI you need to build sbl_uart_uniflash and
sbl_ospi as described in Building MCU+ SDK SBLs. After that you
need to put your board into UART boot mode and flash the
sbl_ospi.release.hs_fs.tiimage file to 0x0 as described in
Flashing data into external flash with the MCU+ SDK. You only have to
do this once.
Then for every new Zephyr firmware build you need convert the Zephyr ELF
Into a RPRC file as described in Creating a SBL bootable RPRC image from
a Zephyr ELF and flash it to 0x80000 as described in Flashing data
into external flash with the MCU+ SDK. After that you can switch into
the OSPI boot mode and run it.
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].