Prepare the target

Before deploying the Topo Template, confirm that the FRDM i.MX 93 board is reachable from your host and that it’s ready for deployment:

    

        
        
topo health --target <user>@<target-ip>

    

Replace <target-ip> with the IP address or hostname of your board.

Resolve any errors before continuing.

The target section includes successful checks similar to:

    

        
        Host
----
Topo: ✅ (topo)
SSH: ✅ (ssh)
Curl: ✅ (curl)
Container Engine: ✅ (docker)

Target
------
Destination: ssh://<target-ip>
Connectivity: ✅
Container Engine: ✅ (docker)
Remoteproc Runtime: ✅ (remoteproc-runtime)
Remoteproc Shim: ✅ (containerd-shim-remoteproc-v1)
Hardware Info: ✅ (lscpu)
Subsystem Driver (remoteproc): ✅ (imx-rproc)

        
    
Note

If remoteproc-runtime is missing, install it with Topo:

    

        
        
topo install remoteproc-runtime --target <user>@<target-ip>

    

Run the health check again:

    

        
        
topo health --target <user>@<target-ip>

    

Reserve memory in the device tree

The web application and Cortex-M33 firmware exchange data through reserved physical memory. The target device tree must reserve memory for the model/input buffer and for the Ethos-U65. This prevents Linux from allocating memory that the firmware and Ethos-U65 need to access by physical address.

You’ll now modify the device tree and reboot the target so that these modifications take effect.

Warning

Back up the board’s original device tree before modifying it. The exact boot partition can differ between Linux images, so check the paths on your board before copying files.

On your host, create a working directory and dump the live device tree from the target:

    

        
        
mkdir -p devicetree
ssh <user>@<target-ip> 'cat /sys/firmware/fdt' > devicetree/live.dtb
dtc -I dtb -O dts -o devicetree/live.dts devicetree/live.dtb

    

Open devicetree/live.dts in a text editor of your choice. Then, under remoteproc-cm33, add the CM33 power domain if it’s not already present:

    

        
        
power-domains = <0x61>;

    

Under reserved-memory, add the model memory range:

    

        
        
model@c0000000 {
    reg = <0x00 0xc0000000 0x00 0x400000>;
    no-map;
};

    

Update the Ethos-U reserved-memory node so it’s reserved and not reusable:

    

        
        
ethosu_region@A8000000 {
    compatible = "shared-dma-pool";
    reg = <0x00 0xa8000000 0x00 0x8000000>;
    no-map;
    phandle = <0x60>;
};

    

Add iomem=relaxed to chosen.bootargs. For example:

    

        
        
bootargs = "clk-imx93.mcore_booted console=ttyLP0,115200 earlycon root=/dev/mmcblk1p2 rootwait rw iomem=relaxed";

    

Return to your host machine terminal and build the patched device tree:

    

        
        
dtc -I dts -O dtb -o devicetree/patched.dtb devicetree/live.dts

    

Copy it to the board:

    

        
        
scp devicetree/patched.dtb <user>@<target-ip>:/tmp/patched.dtb

    

Install it on the board. Adjust the boot partition path if your image uses a different location:

    

        
        
ssh <user>@<target-ip>
cp /run/media/boot-mmcblk1p1/imx93-11x11-frdm.dtb \
   /run/media/boot-mmcblk1p1/imx93-11x11-frdm.dtb.bak
cp /tmp/patched.dtb \
   /run/media/boot-mmcblk1p1/imx93-11x11-frdm.dtb
sync
reboot

    

After the board reboots, run the Topo health check again from the host and verify everything is still correct:

    

        
        
topo health --target <user>@<target-ip>

    

Deploy to the board

You can choose to deploy from the original Topo Template, or from the template you built from scratch. If you haven’t already cloned the original template, clone it now:

    

        
        
topo clone https://github.com/Arm-Examples/topo-imx93-npu-deployment.git

    

Topo prompts for optional build cache image arguments. Accept the defaults unless you have your own cache images.

Note

If you build without cache images, the first build can take a long time and requires about 25 GB of free disk space. The first build involves downloading and building ExecuTorch, the Arm GNU toolchain, MCUX SDK components, RPMsg-Lite, and the Cortex-M33 runner sources. Later builds are faster when Docker can reuse local cache layers or import the configured GHCR cache layers.

Then cd into the correct directory:

    

        
        
cd topo-imx93-npu-deployment

    

Or:

    

        
        
cd new-topo-npu-template

    

Deploy the project to your target:

    

        
        
topo deploy --target <user>@<target-ip>

    

During deployment, Topo builds the required images, transfers them to the target, starts the Cortex-M33 firmware through remoteproc-runtime, and starts the web application.

When deployment succeeds, the output includes a successful service startup. You can also check the deployed services:

    

        
        
topo ps --target <user>@<target-ip>

    

The output shows a process on both the Cortex-M33 and the Linux Host, and is similar to:

    

        
        Image                                   Status          Processing Domain   Address
topo-imx93-npu-deployment-cm33-runner   Up 50 minutes   imx-rproc
topo-imx93-npu-deployment-webapp        Up 50 minutes   Linux Host          imx93-scorpio.cambridge.arm.com:3001, [::]:3001%

        
    

Open the web application

Open the web application in a browser:

    

        
        
http://<target-ip>:3001

    
Note

If you need to use a different target port, set WEBAPP_PORT when deploying. For example:

    

        
        
WEBAPP_PORT=3002 topo deploy --target <user>@<target-ip>

    

Then open:

    

        
        http://<target-ip>:3002

        
    

The application shows:

  • an image selector
  • a Classify button
  • board prerequisite checks
  • classification results
  • an expandable analysis section with runtime details

Image Alt Text:Screenshot of the web interface running on an Arm-based target, showing an image and the model response. This confirms successful deployment and provides a visual reference for the expected result.Image classification web app showing correctly classified German Shepherd

When you choose an image in the browser and select Classify, the web application:

  1. Resizes and normalizes the image to classify into an input tensor compatible with the MobileNetV2 model.
  2. Writes the ExecuTorch .pte program and input tensor into reserved physical memory.
  3. Sends a RUN command to the Cortex-M33 runner over RPMsg.
  4. Waits for the Cortex-M33 firmware to run inference using Ethos-U65 acceleration.
  5. Displays the top-1 and top-5 ImageNet classification results in the browser.

Try this out with an image from an ImageNet-supported class.

What you’ve accomplished

You’ve prepared an FRDM i.MX 93 board for shared-memory NPU inference, deployed the topo-imx93-npu-deployment template with Topo, and started Cortex-M33 firmware through remoteproc-runtime. You used a browser-based application to stage the ExecuTorch .pte program and input tensor for MobileNetV2 classification with Ethos-U65 acceleration.

You can now use the deployed application as a reference for your own heterogeneous Arm applications, or adapt the model, firmware runner, web interface, or Topo metadata for another target.

Back
Next