Skip to main content

Edge AI Reinvents Logistics for Industry 5.0

Combining Human Insight and Edge AI with the NXP i.MX93 FRDM Development Board

Boxes moving along conveyor belt in industrial setting

Image Source: radekcho/stock.adobe.com; generated with AI

By Michael Parks, PE, for Mouser Electronics

Published June 26, 2026

Modern manufacturing and logistics are evolving rapidly, driven by the growing demand for faster, more accurate, and highly flexible operations. Traditional automation, while powerful, often lacks adaptability when systems encounter variability or unforeseen errors, such as missing barcodes or damaged shipping labels. This is where Industry 5.0 principles come into play.

Unlike Industry 4.0, which emphasized total automation and connectivity, Industry 5.0 focuses on collaboration between human operators and intelligent machines. The goal is to combine the precision and speed of automation with human judgment and flexibility, creating workflows that are smarter, safer, and more resilient. At the core of this collaborative model is the deployment of machine learning (ML) at the edge, which involves integrating artificial intelligence (AI) directly at the source of data (i.e., the edge) rather than relying on cloud-based processing. Edge AI enables low-latency and offline decision-making and keeps sensitive data local, addressing privacy and security concerns.

This article presents a prototype of a smart system built on the NXP Semiconductors FRDM-IMX93 development board that verifies the size of a package. The system combines object detection AI, real-time operator interaction, and local processing to address real-world logistics challenges.

Project Materials and Resources

Before beginning any software development, make sure you have all required components and correctly assemble the prototype hardware. This project requires not only the core development board but also specific peripherals to handle video input, graphical output, and operator interaction.

Project Bill of Materials (BOM)

NXP Semiconductors FRDM-IMX93 development kit

Required Software and Downloads

Additional Hardware

  • PC running native Linux (Ubuntu 20.04/22.04 recommended) or Windows 10/11 with Windows Subsystem for Linux (WSL2) enabled
  • Pre-programmed MicroSD card containing the Linux BSP image
  • HDMI monitor
  • HDMI cable
  • USB UVC-compatible camera
  • USB-C PD power supply (5VDC, 1A minimum)
  • USB 2.0 keyboard
  • USB 2.0 mouse
  • USB hub

Resources

Project Technology Overview

This project demonstrates a proof-of-concept package verification station that combines AI-driven automation with human decision-making. The system classifies packages into three size categories using a USB camera and a pre-trained LiteRT (formerly TensorFlow Lite) object-detection model running on the NXP FRDM-IMX93 development board (Figure 1).

Figure 1: Steps for preparing a TensorFlow model for the FRDM-i.MX93. (Source: NXP)

LiteRT is a lightweight, mobile-friendly version of the TensorFlow platform, specifically designed to run ML models efficiently on edge devices such as smartphones, microcontrollers, and embedded systems. When you deploy image recognition with LiteRT, the heavy training process is performed ahead of time (usually on a desktop or cloud server). The trained model is then converted into a compact LiteRT file that can be run on a device.

At runtime, the LiteRT model takes input data—typically an image captured by a camera or loaded from storage—and pre-processes it to match the format the model expects. This often involves resizing the image to a fixed dimension, normalizing pixel values (e.g., scaling them to between 0 and 1), and adding a batch dimension. The prepared image data are fed into the LiteRT interpreter, which uses optimized kernels to run the neural network’s inference operations directly on the device’s central processing unit (CPU), graphics processing unit (GPU), or specialized accelerators, such as on-chip neural processing units (NPUs) or vendor-specific hardware accelerators.

The model processes the input through its layers; for example, convolutional layers extract features like edges and textures, pooling layers downsample the data, and fully connected layers produce the final classification scores. The output is usually a list of probabilities indicating the likelihood that the image belongs to each possible class. The application then interprets these probabilities to produce a result, such as displaying a label (e.g., small, medium, or large) or triggering an action (e.g., lighting an LED, sounding a buzzer).

Because LiteRT models are small and efficient, they enable real-time image recognition even on low-power hardware, making them ideal for Internet of Things (IoT) devices and smart cameras. This on-device approach also improves privacy and reduces the need for constant internet connections, since all computation occurs locally without uploading images to a server.

Hardware Overview

The NXP FRDM-IMX93 is a low-cost, compact development board that incorporates an NXP i.MX 93 processor. The processor is designed for energy-efficient edge computing, with hardware acceleration for ML and secure edge applications. The board includes the following features:

  • CPU: Dual Arm® Cortex®-A55 cores (up to 1.7GHz)
  • Microcontroller core: Arm Cortex-M33 (up to 250MHz) for real-time tasks
  • RAM: 2GB LPDDR4X (onboard)
  • Storage: 32GB eMMC5.1, MicroSD slot
  • NPU: Arm Ethos-U65
  • Integrated security: NXP EdgeLock® secure enclave for crypto, root-of-trust, secure boot
  • Connectivity: 10/100/1000 Ethernet PHY; Wi-Fi® and Bluetooth® connectivity via M.2 socket
  • USB: USB 2.0 OTG and USB 2.0 host ports
  • Expansion: Dual-row, 40-pin header
  • Debug capabilities: JTAG, USB debug port, and onboard OpenSDA debugger

Software Overview

This section describes the various development applications used to update, test, and operate this project. A considerable amount of software is required to run this application. This article will not repeat the NXP documentation in its entirety; however, it will highlight some key points to consider when setting up the development environment on your computer.

In general, the flow of the software development for this project is as follows:

  1. Convert a pre-trained LiteRT model into a format compatible with the NXP hardware.
  2. Create a graphical user interface (GUI) and export the code.
  3. Integrate the LiteRT model and GUI code into an overarching codebase.
  4. Add functionality, such as toggling an LED based on the desired operational logic.

Developing the Project

This section walks through the complete process of bringing an embedded AI and graphical interface project to life on an NXP development board. From connecting your board to the internet and setting up ML inference with the eIQ Toolkit to designing a custom user interface with GUI Guider and integrating the C/C++ application using the Linux cross-compilation toolchain, each step builds on the last to ensure the system works as a unified whole. Follow along carefully to get your device online, run the LiteRT model, display results on your screen, and handle real-world input with custom embedded logic.

The correct sequence for connecting the peripherals ensures the system is ready to boot and receive operator input through the Linux environment:

  1. Connect the USB 2.0 keyboard and USB 2.0 mouse to the USB hub.
  2. Connect the USB hub’s output cable to the USB-A host port on the FRDM-IMX93 development board. This consolidates input devices onto a single host channel.
  3. Connect the USB UVC-compatible camera to an available port on the USB hub. The use of a standard UVC device is essential, as the Linux BSP image running on the i.MX 93’s A55 core generally includes the necessary Video4Linux2 (V4L2) kernel drivers for immediate operation.
  4. Connect the FRDM-IMX93 development board to a standard HDMI monitor using an HDMI cable. The board routes display via an onboard LVDS-to-HDMI bridge to HDMI connector P5.
  5. Connect the USB Type-C PD power supply (minimum 5VDC, 1A) to the USB Type-C PWR input on the FRDM-IMX93 board. Note that this power input is separate from the USB debug port.

To configure the device’s operating system, especially for network access and low-level debugging, it is necessary to establish a reliable serial console connection.

The FRDM-IMX93 includes a dedicated USB debug port (P16) that provides two COM ports: one for the Cortex-A55 system debug (Linux console) and one for the Cortex-M33 system debug. This project requires the Cortex-A55 debug port.

  1. Connect a USB-C cable from the host PC to the FRDM-IMX93’s USB debug port (P16).
  2. On the host PC, open a terminal emulation program (such as PuTTY or Tera Term) and configure the serial connection settings for the Cortex-A55 COM port:
    • 115200 baud rate
    • 8 data bits
    • no parity
    • 1 stop bit (8N1)
  3. Before applying power, ensure the board’s SW1 DIP switch is set to the desired boot configuration. To use the pre-programmed MicroSD card, set SW1 to 0011 (OFF, OFF, ON, ON).
  4. Apply power to the dedicated USB Type-C PWR input port. The board will initiate the boot process, loading the Linux image from the MicroSD card.
  5. Wait for the boot sequence to complete, at which point the Linux command prompt will appear (e.g., root@**imx93frdm**:~#). This prompt confirms full access to the target operating system for subsequent configuration steps.

Deep Dive: The A55 Linux vs. M33 Workflow

This project’s choice of development environment requires a note of clarification. MCUXpresso is traditionally used to develop embedded applications for NXP’s Cortex-M cores (such as the i.MX 93’s M33 core), often involving bare-metal or real-time operating systems.

However, this project’s application requirements—specifically, handling real-time video capture via V4L2, rendering complex graphical elements using Light and Versatile Graphics Library (LVGL) through the Linux framebuffer, and running the comprehensive LiteRT inference engine with NPU delegation—mandate a full operating system environment. These capabilities are inherently complex and best handled by the Linux distribution running on the high-performance Cortex-A55 application cores. Furthermore, the reliance on tools like CMake and Make for building the final executable confirms a standard Linux cross-compilation workflow.

Therefore, this project’s entire development workflow, from compilation to deployment, must focus exclusively on the Linux environment of the Cortex-A55. Establishing this focus prevents developers from using an inappropriate toolchain that lacks the necessary Linux dependencies (such as V4L2, LiteRT delegates, and LVGL libraries) required for the system’s primary functions.

Host Environment Setup and Cross-Compilation Toolchain

The development of this edge AI application requires a sophisticated software stack on the host machine to correctly generate an executable binary for the target hardware. Because the host system typically runs x86 architecture, and the FRDM-IMX93 uses AArch64 (Armv8) architecture, a specialized cross-compilation environment is necessary.

Setting Up the Windows Host Environment with WSL2

Performing the Linux-native cross-compilation from a Windows PC requires the Windows Subsystem for Linux (WSL2). WSL2 provides a full Linux kernel and file system (e.g., Ubuntu) that runs integrated within Windows, allowing access to the required build tools and the NXP Yocto SDK.

  1. In Windows, open an elevated PowerShell or Command Prompt, then run wsl --install.
  2. Follow the prompts to install WSL2 and an Ubuntu distribution (or another compatible Linux distribution). The recommended Linux distributions for WSL2 are Ubuntu 20.04 or 22.04.
  3. Open the new Ubuntu application or type wsl into the Windows search bar to launch the Linux terminal.

Note: You must perform all subsequent steps that involve building, installing, or running scripts in this Linux terminal.

  1. In WSL2, install essential Linux utilities. These core packages (Table 1) are necessary for source control, project building, and network deployment:

Table 1. Essential core packages and commands

Package

Bash Command (Inside WSL2 Terminal)

Purpose

Git

sudo apt update && sudo apt install git

Cloning software repositories

CMake

sudo apt install cmake

Generating the build system

Ninja

sudo apt install ninja-build

Fast execution of the build system

SSH/SCP Client

sudo apt install ssh

Securely deploying the binary to the target board

 

Acquiring and Installing the Yocto SDK

The core of the cross-compilation environment is the NXP Yocto SDK, which contains the correct cross-compiler, system headers, and runtime libraries configured for the i.MX 93 processor and its specific Linux board support package (BSP). As previously noted, this entire process must be executed within the WSL2 Linux terminal.

The compilation process must link the application code—which relies on components such as the LiteRT runtime, V4L2 headers, and LVGL—against the libraries designed for the AArch64 architecture, rather than the host PC’s native libraries. This process is orchestrated by the Yocto SDK, which provides a dedicated cross-compiler and a sysroot (a virtual root file system containing all target-specific dependencies).

The Yocto SDK is tied to a specific NXP Linux BSP release. For best results, use an SDK based on the latest NXP release, such as the one corresponding to the Linux 6.1 or 6.6 BSP (e.g., imx-linux-langdale or imx-linux-scarthgap).

  1. Download the Yocto SDK installer script for the i.MX 93 from the NXP website. (This file is typically named fsl-imx-xwayland-glibc-x86_64-imx-image-full-armv8a-imx93evk-toolchain-6.x.sh, or similar.)
  2. Place the installer file within the WSL2 environment.
  3. Navigate to the download location inside the WSL2 terminal and run the shell script with superuser privileges: $ sudo sh./fsl-imx-xwayland-glibc-x86_64-imx-image-full-armv8a-imx93evk-toolchain-6.x.sh
  4. After installation, you must source the environment setup script provided by the SDK. This command sets the necessary environment variables (e.g., CC, CXX, PATH) that point to the cross-compiler and the AArch64 sysroot. This command must be executed in every new WSL2 terminal session used for compilation: $ source /opt/fsl-imx-xwayland/6.x/environment-setup-aarch64-poky-linux

Failing to source this environment script will cause the CMake utility to use the host PC’s native compiler, resulting in immediate compilation failures when attempting to link against target-specific libraries.

Connecting to the Internet

The final deployment of the compiled application uses Secure Copy Protocol (SCP) over Wi-Fi. This requires the FRDM-IMX93 target board to be connected to the network with a known, active IP address. Because the board is running a Yocto Linux image, network management is typically handled by connmanctl.

The following procedure, executed through the serial console, configures the board’s wireless network connection:

  1. The initial steps load the necessary wireless kernel modules and access the network interface before the connection manager can be used.

#>modprobe moal mod_para=nxp/wifi_mod_para.conf

#>ifconfig mlan0 up

#>connmanctl

 

connmanctl>agent on

connmanctl>enable wifi

connmanctl>scan wifi

connmanctl>services

connmanctl>connect <[your_network-managed_psk]>

  1. Enter your passphrase. The following statement should appear:

Connected <[your_network-managed_psk]>

  1. Type the following to verify the connection:

connmanctl> state       # Should show online state for Wi-Fi

connmanctl> services    # The network should show as “online” or “ready”

connmanctl>quit

#>ping 8.8.8.8          # Should see responses from the server

Once the IP address is obtained, Secure Shell (SSH) and Secure Copy (SCP) access are enabled, allowing the host PC (via the WSL2 terminal) to remotely manage file transfers and executions without requiring physical access to the serial console.

NXP eIQ Machine Learning Software

The ability to perform package verification in real time is built on maximizing the efficiency of the object-detection model. This optimization requires the specialized NXP eIQ Machine Learning software development environment, which facilitates the deployment of models specifically accelerated by the Ethos-U65 NPU.

The NXP eIQ Toolkit is a critical component of the development chain, offering tools for model conversion, optimization, and validation. The information provided here assumes the use of eIQ Toolkit version 1.8.0 or a later compatible release. This toolkit includes support for the LiteRT runtime (often bundled around version 2.18.0 in NXP BSPs) and command-line tools. The eIQ Portal, a GUI component of the toolkit, simplifies the ML workflow for embedded developers. Its primary function in this project is to take a generic pre-trained LiteRT (.tflite) model and tailor it for the i.MX 93’s unique hardware, which ensures optimal utilization of the Arm Ethos-U65 MicroNPU (Figure 2).

Figure 2: The NXP eIQ environment gives developers a variety of tools for deploying the LiteRT model to NXP boards. (Source: Green Shoe Garage)

The standard workflow involves loading the model, converting its numerical precision, delegating network layers to the NPU, and finally exporting the specialized files required by the target application.

Optimizing for the Ethos-U65 NPU

Realizing maximum performance requires adherence to the optimization constraints of the Ethos-U65 hardware, particularly its preference for integer-based arithmetic. This process should be performed using the eIQ Portal GUI (if available on your host environment) or the eIQ command-line tools launched from inside the WSL2 terminal.

Importing the Pre-Trained LiteRT Model

  1. Launch the eIQ Portal or eIQ command line tools by executing eiq_launcher in the WSL2 Bash prompt or by launching the application GUI on Windows.
  2. Click New Project and provide a descriptive name.
  3. Click Import Model, select LiteRT (or TensorFlow Lite), and then browse to select your pre-trained .tflite file.
  4. Use the Model Inspector tool (if applicable) to verify operators and layer compatibility with the NPU.

Quantizing Float32 to Int8

Quantizing Float32 to Int8 is crucial for achieving high performance on the NPU, which is designed for 8-bit integer (Int8) arithmetic.

  1. In the eIQ Portal, navigate to the Optimize tab and select the Quantization
  2. Select Post-Training Quantization (PTQ), then configure the output model precision as Int8.
  3. Click Quantize.
  4. Click Validate to run the dataset through the model. Then review the resulting accuracy score to ensure the Int8 conversion did not degrade performance too much for the logistics task.

Selecting the Ethos-U Delegate

The model must be prepared for hardware acceleration by partitioning the neural network graph.

  1. From the eIQ Toolkit home screen, click the Model Tool
  2. Click Open Model and select your quantized .tflite model.
  3. Open the menu and select the Convert
  4. In the conversion dialog, select Tensorflow Lite Vela/i.MX93 (.tflite) (eiq-converter-armvela).
  5. Click Convert. This will generate the necessary artifacts for the NPU.

These steps tell the runtime to offload supported operations to the NPU. This also ensures compatible network layers are offloaded to the Ethos-U65 MicroNPU, while unsupported layers remain on the Cortex-A55 CPU.

Exporting Optimized Artifacts

The final output is generated for deployment.

  1. Click the Export
  2. Ensure the export process generates:
  • The final, quantized .tflite model (e.g., package_detector_quant.tflite).
  • The necessary runtime configuration and delegate library files (e.g., libethosu_delegate.so).

These optimized artifacts are essential and must be transferred to the FRDM-IMX93 board for deployment.

NXP GUI Guider

The project’s GUI must clearly display the camera feed, the AI’s classification, and the verification status. NXP GUI Guider (Figure 3) is the dedicated drag-and-drop tool used to design this LVGL-based interface. This guide refers to the workflow compatible with GUI Guider versions 1.6.x through 1.9.x. These versions generate code using LVGL versions v8.x.x or v9.x.x.

Figure 3: GUI Guider is a graphical drag-and-drop tool to easily create user interfaces. (Source: Green Shoe Garage)

Initializing GUI Guider and Selecting the Template

The NXP GUI Guider is where the display configuration is set for the i.MX 93’s HDMI output.

  1. Open NXP GUI Guider on the host PC.
  2. Click New Project.
  3. From the list of templates, select the MCIMX93FRDMMX 93 Development Board Template. This template ensures the project configures the correct display resolution and color depth for the board’s HDMI output.
  4. Enter a name in the Project Name field (e.g., BoxDetectionDemo) and specify the output folder in the Project Directory field on the host PC where the source files will be generated.

Designing the UI for Human-in-the-Loop Verification

The GUI design must prioritize clarity and immediate feedback (Figure 4).

Figure 4: This display screen, created in GUI Guider, reflects changes to the packages presented to the camera. (Source: Green Shoe Garage)

  1. Ensure the primary screen (Screen1) is active in the Screen Manager.
  2. From the Widgets panel, drag a Label widget onto the screen. In the Properties panel, rename its ID to a descriptive name, such as Label_Display. This label will display the AI-detected class (e.g., “Small,” “Medium,” or “Large”). The underlying C/C++ application will use this widget to render the live V4L2 camera frames.
  3. Drag a second label widget onto the screen and rename it Label_Status. This label will be programmatically updated to display the verification message (Match/Mismatch) and change color based on the outcome, providing the operator with immediate status.

Exporting the LVGL Source Code

Once the visual layout is complete, export the design.

  1. Click the Export button in the GUI Guider menu.
  2. Verify that GUI Guider generates the portable C source files that define the interface structure, including ui.c, ui.h, and events_init.c.
  3. Manually copy or move the exported files into the WSL2 /source

These exported and copied files are ready for integration with the AI inference and camera code.

Architectural Dependency: LVGL and the Framebuffer Driver

The successful rendering of the GUI on the HDMI monitor relies on a deep integration with the Linux operating system running on the FRDM-IMX93. The initialization code snippet reveals this architecture:

C

lv_init();
fbdev_init();
lv_disp_drv_register();
ui_init();

The calls to fbdev_init() and lv_disp_drv_register() confirm that the LVGL port relies on the standard Linux Framebuffer Device (FBDEV) driver. The framebuffer is the kernel mechanism that manages the display buffer corresponding to the HDMI output. Selecting the correct board template in the GUI Guider ensures that the exported LVGL code is dimensioned correctly to interface with this underlying driver, enabling the compiled application to draw pixels directly to the screen buffer. This low-level dependency ensures that the graphical output is efficient and correctly displayed on the i.MX 93 hardware.

Integrating the Core Application (C/C++) and Implementing Logic

This section details the most complex engineering challenge: integrating the three disparate modules—Camera Input, AI Inference, and GUI Output—into a unified, real-time application and defining the logic that governs the verification process.

Project Structure and Configuring CMake

The core application requires a structured file system and a build definition (CMakeLists.txt) that correctly references all external dependencies using the previously installed Yocto SDK cross-toolchain. The following project structure must be created within the WSL2 Linux file system. The source code for this structure is available in the project’s GitHub repository.

Organizing the Project Files

The project must be structured logically on the host PC (Figure 5):

  • /source: Contains the custom C/C++ files (main.c, logistics_verifier.c) and the exported GUI Guider files (ui.c, events_init.c)
  • /models: Contains the optimized, quantized LiteRT model (package_detector_quant.LiteRT) exported from the eIQ Toolkit
  • /assets: Contains any images or resources used by the application
  • /build: Temporary directory used for compilation output

Figure 5: The minimum file structure for a complete project. (Source: Green Shoe Garage)

Defining the Build System with CMake

The CMakeLists.txt file acts as the project blueprint, instructing the compiler how to build the application for the AArch64 target architecture. It is essential that this file explicitly links against the necessary libraries that were included in the Yocto SDK:

  • Language and Standards: The file defines the project and enforces necessary standards (e.g., C++17).
  • Toolchain Integration: The build must be configured to use the cross-toolchain environment. This is typically done by passing a specific toolchain file (toolchain.cmake) during the CMake configuration step. This file ensures that the build system uses the AArch64 compiler and linker.
  • Library Linking: The file explicitly links against the core libraries:
    • LVGL library
    • LiteRT runtime library
    • V4L2 (Video4Linux2) library for camera interaction
    • Ethos-U Delegate library (required for NPU acceleration)

Implementing the Real-Time Data Pipeline

The central challenge in any vision-based embedded AI application is the high-throughput processing required to move data from the camera sensor to the neural network input layer. The custom C/C++ application addresses this by bypassing high-level overhead and directly managing the low-level Video4Linux2 (V4L2) kernel APIs.

Camera Input (V4L2)

The USB UVC camera connected to the FRDM-IMX93 registers as a V4L2 device, typically located at /dev/video0 on the Linux target. The custom application code handles the low-level V4L2 API calls by:

  • Opening the device file.
  • Querying and setting the desired video format (e.g., YUYV or MJPG) and frame resolution.
  • Initiating memory mapping or user-pointer buffering to manage captured frames efficiently, minimizing copy operations between the kernel and user space.
  • Implementing a continuous loop that dequeues a buffer (capturing a new frame), processes the image, and then enqueues the buffer back for the next frame.

Image Pre-processing

The raw data captured from the V4L2 device (e.g., a YUYV frame) cannot be fed directly into the neural network. Instead, it must be re-processed, which involves:

  • Converting the color space (e.g., YUYV to RGB or grayscale).
  • Scaling the image down to the fixed input dimensions expected by the pre-trained LiteRT model (e.g., 224×224 or 300×300).
  • Scaling the pixel values to match the model’s quantization range (typically 0 to 255 for Int8 models). The correctly pre-processed numerical data is then copied into the input tensor of the LiteRT interpreter.

LiteRT Inference Execution and NPU Delegation

The inference pipeline takes the pre-processed image data and uses the optimized LiteRT model to classify the object.

Initializing the Model and Allocating Tensor

The application code must initialize the LiteRT interpreter using the optimized model file transferred to the target board:

C

LiteRTModel * model = LiteRTModelCreateFromFile("models/model.LiteRT");
// Note: Delegate registration is usually handled by the exported runtime config
LiteRTInterpreter * interpreter = LiteRTInterpreterCreate(model, NULL);
LiteRTInterpreterAllocateTensors(interpreter);

This sequence loads the neural network structure, creates the inference execution context, and allocates memory for the input, intermediate, and output tensors. Crucially, during the interpreter creation phase on the Linux target, the system must recognize and load the Ethos-U delegate library (libethosu_delegate.so) to ensure that compatible operations are directed to the NPU rather than the CPU.

Executing the Inference Loop

Within the main application loop, after the image is pre-processed and loaded into the input tensor, the inference is executed:

C

// Place pre-processed data into input tensor
LiteRTInterpreterInvoke(interpreter);
// Read classification results from output tensor

The LiteRTInterpreterInvoke() function triggers the computation. Due to the delegation, this call transparently dispatches supported layers to the high-speed Ethos-U65 NPU, delivering a classification result (i.e., a class label of Small, Medium, or Large) in near real time.

Implementing the Industry 5.0 Verification Logic

The core logic of this project is not merely object detection, but verification. That is, the system determines whether the detected object matches a dynamically expected parameter.

Dynamic Input and Comparison

The executable is designed to accept the expected package size (e.g., “Large”) as a command-line argument at runtime: ./smart_verifier Large. This expected size represents the required condition, perhaps derived from a manifest or external warehouse management system.

The core logic within the application compares the AI’s detected label (result_label) against the expected label (match_label) provided via the command line.

Integrating GUI and LED Feedback

The logic dictates the system’s response, which is communicated to the operator via the GUI and a physical onboard LED indicator. The code is implemented, often in events_init.c or main.c, using the LVGL update functions.

Match Scenario

If the result_label matches the match_label:
C
if (strcmp(result_label, match_label) == 0) {
    led_off(); // De-assert LED
    snprintf(status_msg, sizeof(status_msg), "%s package detected.", result_label);
    lv_label_set_text(ui_LabelStatus, status_msg); // Update GUI status label
}

This indicates a successful verification, and the alert LED turns off.

Mismatch Scenario (Exception)

If the detected size is different from the expected size (e.g., detecting a “Small” box when expecting “Medium”):

C
else {
    led_on(); // Assert LED
    snprintf(status_msg, sizeof(status_msg), "%s package NOT detected!", result_label);
    lv_label_set_text(ui_LabelStatus, status_msg); // Update GUI status label
}

The LED is activated, providing immediate feedback to the operator that human intervention or visual inspection is required. The LED control functions (led_on/off) abstract the underlying Linux GPIO file-based I/O operations necessary to toggle the physical indicator.

Multithreading for Real-Time User Experience

Due to the computationally intensive nature of the V4L2 camera capture and subsequent AI inference, a multithreading approach is necessary to maintain a smooth, responsive GUI. The provided application code automatically employs two primary threads to ensure a smooth user experience:

  • AI/Camera Thread: This thread is responsible for V4L2 frame grabbing, image pre-processing, LiteRT inference, and executing the core verification logic.
  • LVGL Thread: This thread is dedicated solely to running the LVGL event loop and flushing the display buffers to the Linux framebuffer (fbdev).

By decoupling high-load AI processing from the low-latency display task, the system delivers a superior user experience, which is critical in collaborative industrial environments.

Building, Deploying, and Verifying

The final phase involves compiling the integrated C/C++ source code using the Yocto cross-toolchain, securely deploying the binary and optimized model to the FRDM-IMX93, and executing the application (Figure 6).

Figure 6: The full build of the package-verifying project. (Source: Green Shoe Garage)

Executing the Cross-Compilation

The cross-compilation process must be performed on the host PC within the WSL2 Linux terminal, with the Yocto environment variables previously sourced.

  1. Change to the project root directory and create a temporary directory where the build files will be generated: $ mkdir build && cd build
  2. Point CMake to the cross-compilation toolchain file (toolchain.cmake): $ cmake -DCMAKE_TOOLCHAIN_FILE=../toolchain.cmake .. after sourcing the Yocto SDK (environment-setup-aarch64-poky-linux).
  3. Execute the compilation using the make utility: $ make -j$(nproc)

A successful compilation results in an executable file, named smart_verifier, located within the build/directory in the WSL2 file system.

Secure File Transfer via SCP

The compiled executable and the optimized LiteRT model must be securely transferred to a writable location on the target board via SCP. This command is executed from the WSL2 Linux terminal, using the board’s IP address.

  1. Set up the target directory on the FRDM-IMX93 board via Serial/SSH:
    root@imx93evk:~# mkdir -p /home/root/smart_verifier/models/
  2. Transfer the executable from WSL2 by copying the binary to the target directory:
    $ scp build/smart_verifier root@<board_ip>:/home/root/smart_verifier/
  3. Transfer the model from WSL2 to the FRDM-IMX93 board by copying the optimized, quantized LiteRT model to the designated model directory on the target board:
    $ scp models/*LiteRT root@<board_ip>:/home/root/smart_verifier/models/

The transfer process must use the specific, optimized Int8 model generated in the eIQ Toolkit. Transferring the original Float32 model without quantizing it to Int8 would result in a significant runtime performance penalty, as it would bypass the Ethos-U65 NPU acceleration.

Running and Interacting with the Smart Verifier

The final operational verification is performed by executing the binary directly on the FRDM-IMX93 board via the serial console or an active SSH session.

  1. Navigate to the directory:
    root@imx93evk:~# cd /home/root/smart_verifier
  2. Ensure execution permissions:
    root@imx93evk:~/smart_verifier# chmod +x smart_verifier
  3. Run the application, specifying the expected package size as the dynamic input argument:

Scenario A: Expected Size Is Large

root@imx93evk:~/smart_verifier#./smart_verifier Large 1

Test 1 (Success): Place a package classified as “Large” in front of the camera.
Expected Result: The GUI updates to show “Large package detected.” The status indicator turns green, and the onboard LED is off.

Test 2 (Failure/Exception): Place a package classified as “Small” in front of the camera.
Expected Result: The GUI updates to show “Small package NOT detected!” The status indicator turns red, and the onboard LED lights up, alerting the operator to an exception that requires human oversight.

Scenario B: Expected Size Is Medium

root@imx93evk:~/smart_verifier#./smart_verifier Medium 1

Test 3 (Success): Place a package classified as “Medium” in front of the camera.
Expected Result: The GUI displays a match, and the LED is off.

The definition of package sizes—e.g., up to 6in. registering as small, 6in. to 12in. as medium, and anything larger than 12in. as large—is embedded in the training data of the original LiteRT model.

Troubleshooting Common Deployment Errors

“Cannot Execute Binary File” or Segmentation Faults

The message “Cannot Execute Binary File” indicates that the cross-compilation process failed because the Yocto environment was not correctly sourced, causing the host PC’s native compiler to be used instead of the AArch64 cross-compiler.

Poor Performance

High inference latency (slow FPS) indicates a failure to use the Ethos-U65 NPU. Check that the model was correctly quantized to Int8 in eIQ, and that the delegate library was properly linked and loaded by the LiteRT interpreter at runtime.

Conclusion

As Industry 5.0 continues to evolve and expand, humans and machines will increasingly work together, leveraging the strengths of both to achieve greater efficiency.

This package-verifier project demonstrates how a combination of edge AI and human-in-the-loop decision-making capitalizes on these strengths to ensure reliability and reduce errors that can occur with pure automation. The architecture can be extended to other object classification tasks, integrated with warehouse management systems, or adapted for different form factors. With on-device processing via the FRDM-IMX93’s NPU, the system operates without relying on cloud infrastructure, thereby reducing latency and enhancing privacy. NXP’s eIQ and GUI Guider tools streamline model deployment and interface creation, making it easier for teams of all sizes to bring edge AI solutions to life.

About the Author

Michael Parks, P.E. is the owner of Green Shoe Garage, a custom electronics design studio and technology consultancy located in Southern Maryland. He produces the S.T.E.A.M. Power podcast to help raise public awareness of technical and scientific matters. Michael is also a licensed Professional Engineer in the state of Maryland and holds a Master’s degree in systems engineering from Johns Hopkins University.

Profile Photo of Mike Parks