The i.MX93 SOC platform includes a high efficiency Cortex-M33 processor with security considerations. The Cortex-M33 implements the Armv8-M architecture with Main Extensions, including a single-precision floating-point unit (FPU), a nested vectored interrupt controller (NVIC), flash patch breakpoint (FPB), the data watchpoint and trace (DWT) unit, and instrumentation trace macrocell.
Download the SDK and toolchain
Before building the Cortex-M33 firmware, you must download and install the SDK, which includes example applications and the toolchain to build your firmware application.
Download the SDK
NXP offers an SDK that facilitates firmware development for the Cortex-M33 core. The SDK provides examples demonstrating how to access the peripherals available on this subsystem.
-
Go to https://mcuxpresso.nxp.com/en/builder.
You may have to register with NXP. -
Click Boards > i.MX.
-
Select MCIMX93-EVK.
-
Click the Build MCUXpresso SDK button.
-
Select your Toolchain/IDE and Host OS.
-
Click Download SDK.
Download the toolchain
You must also download the toolchain to build your firmware application.
-
Go to https://developer.arm.com/downloads/-/arm-gnu-toolchain-downloads.
-
Select the latest available version for the Linux hosted "AArch32 bare-metal target" toolchain.
Install the SDK and toolchain
-
Decompress and install the SDK in your Linux PC.
$ tar -xvf <SDK_VER>_MEK-MCIMX93-EVK.tar.gz -C <SDK_VER>_MCIMX93-EVK -
Install the toolchain.
$ tar -xvf arm-gnu-toolchain-14.2.rel1-x86_64-arm-none-eabi.tar.xz -C <toolchain_install_path>
Debug console UART
The Cortex-M33 uses UART2 as default debug console. By default the UART2 is in use on the wireless variant of the ConnectCore 93 by the Bluetooth UART. Therefore, for debug purposes, modify the application code to use a different console port. For instance, change the console port to UART4 (used for XBee, available on the J37 connector, pin2: RX, pin3: TX).
As reference, the changes needed to modify the debug port from UART2 to UART4 are:
/* The UART to use for debug messages. */
-#define BOARD_DEBUG_UART_INSTANCE 2U
+#define BOARD_DEBUG_UART_INSTANCE 4U
#define BOARD_DEBUG_UART_BAUDRATE 115200U
#define BOARD_DEBUG_UART_TYPE kSerialPort_Uart
-#define BOARD_DEBUG_UART_CLOCK_ROOT kCLOCK_Root_Lpuart2
-#define BOARD_DEBUG_UART_CLOCK_GATE kCLOCK_Lpuart2
+#define BOARD_DEBUG_UART_CLOCK_ROOT kCLOCK_Root_Lpuart4
+#define BOARD_DEBUG_UART_CLOCK_GATE kCLOCK_Lpuart4
- IOMUXC_SetPinMux(IOMUXC_PAD_UART2_RXD__LPUART2_RX, 0U);
- IOMUXC_SetPinMux(IOMUXC_PAD_UART2_TXD__LPUART2_TX, 0U);
+ IOMUXC_SetPinMux(IOMUXC_PAD_ENET2_RD0__LPUART4_RX, 0U);
+ IOMUXC_SetPinMux(IOMUXC_PAD_ENET2_TD0__LPUART4_TX, 0U);
- IOMUXC_SetPinConfig(IOMUXC_PAD_UART2_RXD__LPUART2_RX,
+ IOMUXC_SetPinConfig(IOMUXC_PAD_ENET2_RD0__LPUART4_RX,
IOMUXC_PAD_PD_MASK);
- IOMUXC_SetPinConfig(IOMUXC_PAD_UART2_TXD__LPUART2_TX,
+ IOMUXC_SetPinConfig(IOMUXC_PAD_ENET2_TD0__LPUART4_TX,
IOMUXC_PAD_DSE(15U));
Build a demo application
-
To build the hello_world example, export the variable
ARMGCC_DIRwith the absolute path to the GCC ARM Embedded toolchain.$ export ARMGCC_DIR=<toolchain_install_path>/arm-gnu-toolchain-14.2.rel1-x86_64-arm-none-eabi -
Build the application.
$ cd ${SDK_INSTALL_DIR}/<SDK_VER>_MCIMX93-EVK/boards/mcimx93evk/demo_apps/hello_world/armgcc $ ./build_release.shYou can find the artifacts from a successful build in the
releasedirectory.
| For more information, see the MCUXpresso Software Development Kit |
Containerize the demo application
To run the Cortex-M33 firmware, you must embed it in an AHAB container.
-
Install the Digi Embedded Yocto SDK.
See Install a pre-compiled toolchain for instructions.
-
Source the Digi Embedded Yocto SDK environment.
$ . /opt/dey/5.0-r3/ccimx93-dvk/environment-setup-armv8a-dey-linux -
Create the AHAB container from your firmware image.
$ mkimage_imx8 -soc IMX9 -c -m33 hello_world.bin 0 0x1FFE0000 0x201E0000 -out hello_world_cntr.bin
Transfer and run the demo application
-
Boot your device and stop in the U-Boot console.
-
Transfer the application to RAM, for example via TFTP:
=> tftp $loadaddr hello_world_cntr.bin Using ethernet@428a0000 device TFTP from server 192.168.123.100; our IP address is 192.168.2.170 Filename 'hello_world_cntr.bin'. Load address: 0x80400000 Loading: # 3 MiB/s done Bytes transferred = 6268 (187c hex) -
Use the
bootaux_cntrcommand to run the application on the Cortex-M33:=> bootaux_cntr $loadaddr 0 Authenticate auxcore container at 0x80400000 ## Starting auxiliary core addr = 0x1FFE0000...
Linux remoteproc framework
Modern SoCs typically have remote processing devices on the same chip silicon. The remoteproc framework allows different platforms/architectures to control (power on, load firmware, power off) those remote processors.
| The firmware file must be in ELF format to be used with the remoteproc framework. |
Enable the remoteproc framework
remoteproc support is enabled as built-in on the ConnectCore 93 Development Kit kernel configuration file.
-
Linux remoteproc framework (
CONFIG_REMOTEPROC) -
IMX remoteproc driver (
CONFIG_IMX_REMOTEPROC)
Control remote processors with remoteproc framework
You can use the remoteproc framework to load firmware onto an SoC and power it off and on. The location of the remoteproc device is available in the file system at:
# /sys/class/remoteproc/remoteprocX
Where X is the index of the device node, by default 0.
Use the following commands to load, start, and stop the Cortex-M33 firmware:
# echo -n <firmware_name.elf> > /sys/class/remoteproc/remoteproc0/firmware
# echo start > /sys/class/remoteproc/remoteproc0/state
# echo stop > /sys/class/remoteproc/remoteproc0/state
You can monitor the state of the remoteproc firmware with:
# cat /sys/class/remoteproc/remoteproc0/state