Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
178 changes: 178 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ on:
branches: [ main, master, dev, 'feat/**' ]
pull_request:
branches: [ main, master, dev ]
workflow_dispatch:

jobs:
build-riscv-polarfire:
Expand Down Expand Up @@ -262,3 +263,180 @@ jobs:
- name: Run Deterministic Headless Renode Test
run: |
python3 targets/STMicroelectronics/NUCLEO_F401RE/scripts/test_renode.py

build-arm-nxp:
name: Build NXP i.MX RT1064 (ARM Cortex-M7)
runs-on: ubuntu-24.04

env:
GCC_VERSION: 14.3.rel1
GCC_TARGET: arm-none-eabi
CMSIS_VERSION: 5.9.0
NXP_DFP_VERSION: 15.1.0

steps:
- name: Checkout Repository
uses: actions/checkout@v4
with:
submodules: recursive

- name: Install CMake and Ninja
run: |
sudo apt-get update
sudo apt-get install -y cmake ninja-build

- name: Cache the Arm GNU toolchain
id: cache-arm-gcc
uses: actions/cache@v4
with:
path: toolchain
key: arm-gnu-toolchain-${{ env.GCC_VERSION }}-x86_64-${{ env.GCC_TARGET }}

- name: Install the Arm GNU toolchain
if: steps.cache-arm-gcc.outputs.cache-hit != 'true'
run: |
set -eu
base="https://developer.arm.com/-/media/Files/downloads/gnu/${GCC_VERSION}/binrel"
archive="arm-gnu-toolchain-${GCC_VERSION}-x86_64-${GCC_TARGET}.tar.xz"
mkdir -p toolchain && cd toolchain
curl -fsSLO "$base/$archive"
curl -fsSLO "$base/$archive.sha256asc"
sha256sum -c "$archive.sha256asc"
tar xf "$archive"
rm -f "$archive"

- name: Put the toolchain on PATH
run: |
set -eu
echo "$GITHUB_WORKSPACE/toolchain/arm-gnu-toolchain-${GCC_VERSION}-x86_64-${GCC_TARGET}/bin" >> "$GITHUB_PATH"

- name: Report the toolchain version
run: ${{ env.GCC_TARGET }}-gcc --version

- name: Cache NXP SDK & CMSIS Dependencies
id: cache-nxp-sdk
uses: actions/cache@v4
with:
path: targets/NXP/MIMXRT1064-EVK/lib/mcux-sdk
key: nxp-sdk-${{ env.NXP_DFP_VERSION }}-cmsis-${{ env.CMSIS_VERSION }}-${{ hashFiles('targets/NXP/MIMXRT1064-EVK/scripts/fetch_sdk.sh') }}

- name: Fetch NXP SDK & CMSIS Dependencies
if: steps.cache-nxp-sdk.outputs.cache-hit != 'true'
run: |
bash targets/NXP/MIMXRT1064-EVK/scripts/fetch_sdk.sh

- name: Build All NXP MIMXRT1064-EVK Demos
run: |
bash targets/NXP/MIMXRT1064-EVK/scripts/build.sh --demo all --rebuild

- name: Verify Built NXP ELFs
run: |
test -f targets/NXP/MIMXRT1064-EVK/build/app/demos/threadx_basic/mimxrt1064_threadx.elf
test -f targets/NXP/MIMXRT1064-EVK/build/app/demos/netx_echo/mimxrt1064_threadx.elf
test -f targets/NXP/MIMXRT1064-EVK/build/app/demos/netx_echo/mimxrt1064_client.elf
test -f targets/NXP/MIMXRT1064-EVK/build/app/demos/netx_trng_console/mimxrt1064_threadx.elf
test -f targets/NXP/MIMXRT1064-EVK/build/app/demos/netx_trng_console/mimxrt1064_client.elf
echo "[OK] All NXP MIMXRT1064-EVK demo ELFs verified."

- name: Archive Built NXP ELFs
uses: actions/upload-artifact@v4
with:
name: nxp-mimxrt1064-demo-elfs
path: targets/NXP/MIMXRT1064-EVK/build/app/demos/
retention-days: 1

test-nxp-renode:
name: Headless Renode Emulation & Assertion Test (NXP i.MX RT1064)
needs: build-arm-nxp
runs-on: ubuntu-24.04
timeout-minutes: 15
env:
RENODE_VERSION: 1.16.1
RENODE_SHA256: 1a532d4b5b82de0dd154970c401e0c7b0e498d17304b2cecc007e306c8f9617c

steps:
- name: Checkout Repository
uses: actions/checkout@v4
with:
submodules: recursive

- name: Set Up Python
uses: actions/setup-python@v5
with:
python-version: "3.11"

- name: Download Built NXP ELFs
uses: actions/download-artifact@v4
with:
name: nxp-mimxrt1064-demo-elfs
path: targets/NXP/MIMXRT1064-EVK/build/app/demos

- name: Inspect Downloaded ELF Artifacts
run: |
echo "=== Extracted NXP Demo ELF Artifacts ==="
ls -laR targets/NXP/MIMXRT1064-EVK/build/app/demos/

- name: Cache the portable Renode environment
id: cache-renode
uses: actions/cache@v4
with:
path: ~/renode
key: renode-${{ env.RENODE_VERSION }}-linux-portable

- name: Install Pinned Portable Renode Emulation Environment
if: steps.cache-renode.outputs.cache-hit != 'true'
run: |
set -euo pipefail
TARBALL="renode-${RENODE_VERSION}.linux-portable.tar.gz"
wget -q "https://github.com/renode/renode/releases/download/v${RENODE_VERSION}/${TARBALL}"
echo "${RENODE_SHA256} ${TARBALL}" | sha256sum --check --strict
mkdir -p $HOME/renode
tar -xzf "${TARBALL}" -C $HOME/renode --strip-components=1
rm "${TARBALL}"

- name: Install Renode System Prerequisites
run: |
sudo apt-get update -qq
sudo apt-get install -y -qq libx11-6 libxkbcommon-x11-0 libxcb1 strace

- name: Put Renode on PATH
run: echo "$HOME/renode" >> $GITHUB_PATH

- name: Link Renode Scripts & Dependencies
run: |
ln -sf $HOME/renode/scripts $HOME/renode/bin/scripts 2>/dev/null || true
ln -sf $HOME/renode/platforms $HOME/renode/bin/platforms 2>/dev/null || true

- name: Report Runner Environment & Diagnostics
run: |
echo "=== System Architecture & Kernel ==="
uname -a
lsb_release -a
echo "=== Renode Version ==="
renode --version
echo "=== Python Version ==="
python3 --version


- name: Run Deterministic Headless Renode Test (threadx_basic)
run: |
python3 targets/NXP/MIMXRT1064-EVK/scripts/test_renode.py --demo threadx_basic

- name: Run Deterministic Headless Renode Test (netx_echo)
run: |
python3 targets/NXP/MIMXRT1064-EVK/scripts/test_renode.py --demo netx_echo

- name: Run Deterministic Headless Renode Test (netx_trng_console)
run: |
python3 targets/NXP/MIMXRT1064-EVK/scripts/test_renode.py --demo netx_trng_console --seed 12345

- name: Upload Renode Execution Logs
if: always()
uses: actions/upload-artifact@v4
with:
name: nxp-renode-execution-logs
path: |
targets/NXP/MIMXRT1064-EVK/build/*.log
targets/NXP/MIMXRT1064-EVK/*.log
if-no-files-found: ignore

10 changes: 10 additions & 0 deletions targets/NXP/MIMXRT1064-EVK/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Build artifacts
build/
*.elf
*.bin
*.hex
*.map

# Downloaded SDK dependencies
lib/mcux-sdk/
temp_fetch/
166 changes: 166 additions & 0 deletions targets/NXP/MIMXRT1064-EVK/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
# Copyright (c) 2026 Eclipse ThreadX contributors

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Blocking, placement. This whole tree should live at targets/NXP/MIMXRT1064-EVK/, not at the repository root.

docs/architecture.md section 4 describes onboarding a board as: create targets/<Vendor>/<Board_Name>/ from templates/target/, then implement the interfaces in bsp/include/bsp/. The root-level vendor directories are the pre-framework set that section 1 explicitly freezes, and adding a fourth reopens it.

Beyond the move, the board needs to implement bsp_board_init, bsp_led_init/on/off/toggle and bsp_console_init/write. board_init() and console_write() here are the right implementations, they just need to sit behind those names so the demos can be built against the contract rather than against this board.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I relocated the target directory to targets/NXP/MIMXRT1064-EVK/ per repository architecture guidelines. I also implemented the standard BSP interfaces under lib/bsp so application demos link against the contract rather than board-specific functions.

#
# This program and the accompanying materials are made available
# under the terms of the MIT license which is available at
# https://opensource.org/license/mit.
#
# SPDX-License-Identifier: MIT
#
# Contributors:
# Ali Eissa - 2026 version.

cmake_minimum_required(VERSION 3.10 FATAL_ERROR)
set(CMAKE_C_STANDARD 99)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)

# Set the toolchain if not defined
if(NOT CMAKE_TOOLCHAIN_FILE)
set(CMAKE_TOOLCHAIN_FILE "${CMAKE_CURRENT_LIST_DIR}/cmake/arm-gcc-cortex-m7.cmake")
endif()

list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}/cmake)

include(utilities)

# Define the Project
project(mimxrt1064_threadx C CXX ASM)

# Select demo to build: all (default), threadx_basic, netx_echo, netx_trng_console
set(ACTIVE_DEMO "all" CACHE STRING "Active demo name to build: all, netx_echo, netx_trng_console, threadx_basic")

# Set up paths for MCUXpresso SDK
set(SDK_DIR "${CMAKE_CURRENT_LIST_DIR}/lib/mcux-sdk")
if(NOT EXISTS "${SDK_DIR}/devices/MIMXRT1064/MIMXRT1064.h")
message(FATAL_ERROR "NXP SDK dependencies missing! Please run 'scripts/fetch_sdk.ps1' or 'scripts/fetch_sdk.sh' first.")
endif()

# Dynamic Middleware Configuration
if(NOT ACTIVE_DEMO STREQUAL "all" AND EXISTS "${CMAKE_CURRENT_LIST_DIR}/app/demos/${ACTIVE_DEMO}/nx_user.h")
set(NX_USER_FILE "${CMAKE_CURRENT_LIST_DIR}/app/demos/${ACTIVE_DEMO}/nx_user.h" CACHE STRING "Enable NetX Duo user configuration" FORCE)
else()
set(NX_USER_FILE "${CMAKE_CURRENT_LIST_DIR}/lib/netxduo/nx_user.h" CACHE STRING "Enable NetX Duo user configuration" FORCE)
endif()

if(NOT ACTIVE_DEMO STREQUAL "all" AND EXISTS "${CMAKE_CURRENT_LIST_DIR}/app/demos/${ACTIVE_DEMO}/tx_user.h")
set(TX_USER_FILE "${CMAKE_CURRENT_LIST_DIR}/app/demos/${ACTIVE_DEMO}/tx_user.h" CACHE STRING "Enable TX user configuration" FORCE)
set(TX_USER_FILE_DIR "${CMAKE_CURRENT_LIST_DIR}/app/demos/${ACTIVE_DEMO}")
else()
set(TX_USER_FILE "${CMAKE_CURRENT_LIST_DIR}/lib/threadx/tx_user.h" CACHE STRING "Enable TX user configuration" FORCE)
set(TX_USER_FILE_DIR "${CMAKE_CURRENT_LIST_DIR}/lib/threadx")
endif()

get_filename_component(WORKSPACE_ROOT "${CMAKE_CURRENT_LIST_DIR}/../../.." ABSOLUTE)
set(SHARED_LIB_DIR "${WORKSPACE_ROOT}/libs")
set(SHARED_BSP_DIR "${WORKSPACE_ROOT}/bsp")

# Compile ThreadX Kernel from root shared libs submodule
set(THREADX_DIR "${SHARED_LIB_DIR}/threadx")
add_subdirectory(${THREADX_DIR} threadx)

# Compile NetX Duo TCP/IP Stack from root shared libs submodule (cached for networking demos)
set(NXD_ENABLE_FILE_SERVERS OFF CACHE BOOL "Disable FileX dependency in NetX Duo" FORCE)
set(NETXDUO_DIR "${SHARED_LIB_DIR}/netxduo")
add_subdirectory(${NETXDUO_DIR} netxduo)

# Common board configuration interface carrying compile definitions and core SDK include directories
add_library(mimxrt1064_common INTERFACE)

target_compile_definitions(mimxrt1064_common
INTERFACE
CPU_MIMXRT1064DVL6A
XIP_EXTERNAL_FLASH=1
XIP_BOOT_HEADER_ENABLE=1
XIP_BOOT_HEADER_DCD_ENABLE=1
FSL_SDK_DRIVER_QUICK_ACCESS_ENABLE=1
SDK_DEBUGCONSOLE=1
SKIP_SYSCLK_INIT=1
__STARTUP_INITIALIZE_NONCACHEDATA=1
)

target_include_directories(mimxrt1064_common
INTERFACE
${SDK_DIR}/CMSIS/Include
${SDK_DIR}/devices/MIMXRT1064
${SDK_DIR}/drivers
${SDK_DIR}/board
${SDK_DIR}/utilities
${SDK_DIR}/components/uart
${CMAKE_CURRENT_LIST_DIR}/app
${TX_USER_FILE_DIR}
)

# Compile the NXP MCUXpresso Driver & Board Library as an Object Library
set(SDK_TARGET mcux_sdk)

add_library(${SDK_TARGET} OBJECT
${SDK_DIR}/devices/MIMXRT1064/system_MIMXRT1064.c
${SDK_DIR}/devices/MIMXRT1064/fsl_flexspi_nor_boot.c
${SDK_DIR}/drivers/fsl_clock.c
${SDK_DIR}/drivers/fsl_common.c
${SDK_DIR}/drivers/fsl_common_arm.c
${SDK_DIR}/drivers/fsl_gpio.c
${SDK_DIR}/drivers/fsl_lpuart.c
${SDK_DIR}/board/board.c
${SDK_DIR}/board/clock_config.c
${SDK_DIR}/board/pin_mux.c
${SDK_DIR}/board/dcd.c
${SDK_DIR}/board/evkmimxrt1064_flexspi_nor_config.c
${SDK_DIR}/utilities/fsl_debug_console.c
${SDK_DIR}/utilities/fsl_str.c
${SDK_DIR}/utilities/fsl_assert.c
${SDK_DIR}/components/uart/fsl_adapter_lpuart.c
)

target_link_libraries(${SDK_TARGET}
PUBLIC
mimxrt1064_common
)

# 1. Define Board Support Package library
add_subdirectory(lib/bsp)

# 2. Define NetX Duo driver library targets (cached for networking demos)
add_library(netx_imxrt_driver_common INTERFACE)

target_include_directories(netx_imxrt_driver_common
INTERFACE
${CMAKE_CURRENT_LIST_DIR}/lib/netx_driver
${CMAKE_CURRENT_LIST_DIR}/lib/phyksz8081
${CMAKE_CURRENT_LIST_DIR}/lib/netxduo
)

target_compile_options(netx_imxrt_driver_common
INTERFACE
-Wno-unused-variable
)

target_link_libraries(netx_imxrt_driver_common
INTERFACE
mimxrt1064_common
netxduo
threadx
mcux_sdk
)

set(NETX_DRIVER_SOURCES
${CMAKE_CURRENT_LIST_DIR}/lib/netx_driver/nx_driver_imxrt1062.c
${CMAKE_CURRENT_LIST_DIR}/lib/netx_driver/gnu/nx_driver_imxrt1062_low_level.S
${CMAKE_CURRENT_LIST_DIR}/lib/phyksz8081/fsl_phy.c
${SDK_DIR}/drivers/fsl_enet.c
)

add_library(netx_imxrt_driver OBJECT ${NETX_DRIVER_SOURCES})
target_link_libraries(netx_imxrt_driver PUBLIC netx_imxrt_driver_common)

add_library(netx_imxrt_driver_client OBJECT ${NETX_DRIVER_SOURCES})
target_link_libraries(netx_imxrt_driver_client PUBLIC netx_imxrt_driver_common)
target_compile_definitions(netx_imxrt_driver_client PUBLIC NETX_CLIENT_NODE=1)

# 3. Add demo subdirectories to build executable targets
if(ACTIVE_DEMO STREQUAL "all")
add_subdirectory(app/demos/threadx_basic)
add_subdirectory(app/demos/netx_echo)
add_subdirectory(app/demos/netx_trng_console)
else()
add_subdirectory(app/demos/${ACTIVE_DEMO})
endif()
Loading
Loading