From 8e5d6b9bf48da3e0dd4a0ff573297ef9d94808fe Mon Sep 17 00:00:00 2001 From: Ali Eissa Date: Wed, 9 Sep 2026 15:12:59 +0400 Subject: [PATCH 01/11] Project Skeleton & Toolchain Setup Signed-off-by: Ali Eissa Assisted-by: Google DeepMind Antigravity --- NXP/MIMXRT1064-EVK/.gitignore | 10 ++ NXP/MIMXRT1064-EVK/CMakeLists.txt | 84 +++++++++ NXP/MIMXRT1064-EVK/NOTICE.md | 61 +++++++ NXP/MIMXRT1064-EVK/README.md | 88 +++++++++ .../cmake/arm-gcc-cortex-m7.cmake | 20 +++ .../cmake/arm-gcc-cortex-toolchain.cmake | 77 ++++++++ NXP/MIMXRT1064-EVK/cmake/utilities.cmake | 50 ++++++ NXP/MIMXRT1064-EVK/lib/threadx/tx_user.h | 26 +++ NXP/MIMXRT1064-EVK/scripts/build.ps1 | 84 +++++++++ NXP/MIMXRT1064-EVK/scripts/build.sh | 77 ++++++++ NXP/MIMXRT1064-EVK/scripts/fetch_sdk.ps1 | 169 ++++++++++++++++++ NXP/MIMXRT1064-EVK/scripts/fetch_sdk.sh | 128 +++++++++++++ 12 files changed, 874 insertions(+) create mode 100644 NXP/MIMXRT1064-EVK/.gitignore create mode 100644 NXP/MIMXRT1064-EVK/CMakeLists.txt create mode 100644 NXP/MIMXRT1064-EVK/NOTICE.md create mode 100644 NXP/MIMXRT1064-EVK/README.md create mode 100644 NXP/MIMXRT1064-EVK/cmake/arm-gcc-cortex-m7.cmake create mode 100644 NXP/MIMXRT1064-EVK/cmake/arm-gcc-cortex-toolchain.cmake create mode 100644 NXP/MIMXRT1064-EVK/cmake/utilities.cmake create mode 100644 NXP/MIMXRT1064-EVK/lib/threadx/tx_user.h create mode 100644 NXP/MIMXRT1064-EVK/scripts/build.ps1 create mode 100644 NXP/MIMXRT1064-EVK/scripts/build.sh create mode 100644 NXP/MIMXRT1064-EVK/scripts/fetch_sdk.ps1 create mode 100644 NXP/MIMXRT1064-EVK/scripts/fetch_sdk.sh diff --git a/NXP/MIMXRT1064-EVK/.gitignore b/NXP/MIMXRT1064-EVK/.gitignore new file mode 100644 index 00000000..c44f7285 --- /dev/null +++ b/NXP/MIMXRT1064-EVK/.gitignore @@ -0,0 +1,10 @@ +# Build artifacts +build/ +*.elf +*.bin +*.hex +*.map + +# Downloaded SDK dependencies +lib/mcux-sdk/ +temp_fetch/ diff --git a/NXP/MIMXRT1064-EVK/CMakeLists.txt b/NXP/MIMXRT1064-EVK/CMakeLists.txt new file mode 100644 index 00000000..66d6593d --- /dev/null +++ b/NXP/MIMXRT1064-EVK/CMakeLists.txt @@ -0,0 +1,84 @@ +# Copyright (c) 2026 Eclipse ThreadX contributors +# +# 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.5 FATAL_ERROR) +set(CMAKE_C_STANDARD 99) + +# 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) + +# Define ThreadX User Configurations +set(TX_USER_FILE "${CMAKE_CURRENT_LIST_DIR}/lib/threadx/tx_user.h" CACHE STRING "Enable TX user configuration") +set(TX_USER_FILE_DIR "${CMAKE_CURRENT_LIST_DIR}/lib/threadx") + +# 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() + +# 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_compile_definitions(${SDK_TARGET} + PUBLIC + 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 +) + +target_include_directories(${SDK_TARGET} + PUBLIC + ${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 ThreadX Kernel from root shared libs submodule +set(THREADX_DIR "${CMAKE_CURRENT_LIST_DIR}/../../libs/threadx") +add_subdirectory(${THREADX_DIR} threadx) diff --git a/NXP/MIMXRT1064-EVK/NOTICE.md b/NXP/MIMXRT1064-EVK/NOTICE.md new file mode 100644 index 00000000..854858e9 --- /dev/null +++ b/NXP/MIMXRT1064-EVK/NOTICE.md @@ -0,0 +1,61 @@ +# Third-Party Software Notices + +This directory contains build automation scripts and configurations that download and compile third-party software components. This notice lists the licenses and copyrights applicable to those components. + +--- + +## 1. NXP MCUXpresso SDK Drivers & Device Support +* **Source**: https://github.com/nxp-mcuxpresso/mcuxsdk-core / https://mcuxpresso.nxp.com/ +* **License**: BSD 3-Clause + +```text +Copyright 2016-2026 NXP +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +``` + +--- + +## 2. ARM CMSIS Core +* **Source**: https://github.com/ARM-software/CMSIS_5 / https://github.com/STMicroelectronics/cmsis-core +* **License**: Apache License 2.0 + +```text +Copyright (c) 2009-2025 Arm Limited. All rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +``` diff --git a/NXP/MIMXRT1064-EVK/README.md b/NXP/MIMXRT1064-EVK/README.md new file mode 100644 index 00000000..c972249e --- /dev/null +++ b/NXP/MIMXRT1064-EVK/README.md @@ -0,0 +1,88 @@ +# NXP i.MX RT1064-EVK Board Support Package & Demos + +This directory contains the Board Support Package (BSP) and build environment for running the **Eclipse ThreadX RTOS** and **NetX Duo** on the **NXP i.MX RT1064-EVK** evaluation board (ARM Cortex-M7 @ 600 MHz). + +The project is designed to run seamlessly both in the **Antmicro Renode** simulation framework and on physical silicon. + +--- + +## Hardware Configuration + +* **Development Board**: MIMXRT1064-EVK +* **Microcontroller**: NXP i.MX RT1064 (MIMXRT1064DVL6A, ARM Cortex-M7 @ 600 MHz) +* **Flash Memory**: 4 MB internal FlexSPI NOR Flash (XIP) +* **Internal SRAM**: 1 MB on-chip RAM (Configurable as ITCM, DTCM, and OCRAM) +* **Debug Serial Console**: LPUART1 (115,200 baud, 8N1) +* **User LED**: GPIO9 Pin 3 (`GPIO_AD_B0_09`) / User LED (Green) +* **Virtual Networking**: ENET1 (10/100M Fast Ethernet MAC via KSZ8081 PHY) + +--- + +## Project Structure + +```text +NXP/MIMXRT1064-EVK/ +├── CMakeLists.txt # Top-level CMake build configuration +├── NOTICE.md # Third-party licensing notices (NXP BSD-3 & CMSIS) +├── README.md # This documentation file +├── cmake/ +│ ├── arm-gcc-cortex-m7.cmake # CPU architecture and FPU definitions +│ ├── arm-gcc-cortex-toolchain.cmake # GNU toolchain discovery and compiler flags +│ └── utilities.cmake # Elf-to-bin/hex conversion and linker macros +├── lib/ +│ ├── threadx/ +│ │ └── tx_user.h # ThreadX configuration (hardware FPU enabled) +│ └── mcux-sdk/ # Official NXP SDK drivers (fetched via script) +└── scripts/ + ├── fetch_sdk.ps1 / .sh # Download official NXP drivers, device headers & CMSIS + └── build.ps1 / .sh # One-command build script with Ninja/CMake +``` + +--- + +## Prerequisites + +Before building, ensure the following cross-compilation tools are installed and present on your `PATH`: + +* **ARM GNU Toolchain** (`arm-none-eabi-gcc` 10.3 or newer) +* **CMake** (version 3.5 or newer) +* **Ninja** (or **Make**) +* **Git** (for downloading SDK dependencies) +* **Antmicro Renode** (v1.15 or newer, for simulation) + +--- + +## Quick Start Guide + +### 1. Download SDK Dependencies +Run the driver fetcher script to retrieve official NXP MCUXpresso SDK drivers, CMSIS device headers, and board files: + +* **On Windows (PowerShell)**: + ```powershell + powershell -ExecutionPolicy Bypass -File .\scripts\fetch_sdk.ps1 + ``` +* **On Linux / macOS (Bash)**: + ```bash + chmod +x ./scripts/fetch_sdk.sh + ./scripts/fetch_sdk.sh + ``` + +### 2. Build the Project +Compile the application, vendor drivers, and Eclipse ThreadX kernel: + +* **On Windows (PowerShell)**: + ```powershell + powershell -ExecutionPolicy Bypass -File .\scripts\build.ps1 -Rebuild + ``` +* **On Linux / macOS (Bash)**: + ```bash + chmod +x ./scripts/build.sh + ./scripts/build.sh --rebuild + ``` + +--- + +## Hardware Verification Status + +> [!NOTE] +> This Board Support Package is developed and validated using **Antmicro Renode simulation**. Physical hardware verification on the EVK-MIMXRT1064 evaluation board is welcome and encouraged! diff --git a/NXP/MIMXRT1064-EVK/cmake/arm-gcc-cortex-m7.cmake b/NXP/MIMXRT1064-EVK/cmake/arm-gcc-cortex-m7.cmake new file mode 100644 index 00000000..c22c25b3 --- /dev/null +++ b/NXP/MIMXRT1064-EVK/cmake/arm-gcc-cortex-m7.cmake @@ -0,0 +1,20 @@ +# Copyright (c) 2026 Eclipse ThreadX contributors +# +# 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. + +# Define the CPU architecture for ThreadX +set(THREADX_ARCH "cortex_m7") +set(THREADX_TOOLCHAIN "gnu") + +# Cortex-M7 compiler options for NXP i.MX RT1064 +set(MCPU_FLAGS "-mthumb -mcpu=cortex-m7") +set(VFP_FLAGS "-mfloat-abi=hard -mfpu=fpv5-d16") + +include(${CMAKE_CURRENT_LIST_DIR}/arm-gcc-cortex-toolchain.cmake) diff --git a/NXP/MIMXRT1064-EVK/cmake/arm-gcc-cortex-toolchain.cmake b/NXP/MIMXRT1064-EVK/cmake/arm-gcc-cortex-toolchain.cmake new file mode 100644 index 00000000..0fe01f90 --- /dev/null +++ b/NXP/MIMXRT1064-EVK/cmake/arm-gcc-cortex-toolchain.cmake @@ -0,0 +1,77 @@ +# Copyright (c) Microsoft +# Copyright (c) 2026 Eclipse ThreadX contributors +# +# 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: +# Microsoft - Initial version +# Frédéric Desbiens - 2024 version. +# Ali Eissa - 2026 version. + +set(CMAKE_SYSTEM_NAME Generic) +set(CMAKE_SYSTEM_PROCESSOR arm) +set(TARGET_TRIPLET "arm-none-eabi-") + +# Default to Debug build +if(NOT CMAKE_BUILD_TYPE) + set(CMAKE_BUILD_TYPE "Debug" CACHE STRING "Choose the type of build, options are: Debug Release." FORCE) +endif() + +# Windows executable suffix handling +if(WIN32) + set(TOOLCHAIN_EXT ".exe") +else() + set(TOOLCHAIN_EXT "") +endif() + +find_program(COMPILER_ON_PATH "${TARGET_TRIPLET}gcc${TOOLCHAIN_EXT}") + +if(DEFINED ENV{ARM_GCC_PATH}) + file(TO_CMAKE_PATH $ENV{ARM_GCC_PATH} ARM_TOOLCHAIN_PATH) + message(STATUS "Using ENV variable ARM_GCC_PATH = ${ARM_TOOLCHAIN_PATH}") +elseif(COMPILER_ON_PATH) + get_filename_component(ARM_TOOLCHAIN_PATH ${COMPILER_ON_PATH} DIRECTORY) + message(STATUS "Using ARM GCC from PATH = ${ARM_TOOLCHAIN_PATH}") +else() + message(FATAL_ERROR "Unable to find ARM GCC (${TARGET_TRIPLET}gcc). Either add it to your PATH, or define ARM_GCC_PATH to the compiler directory.") +endif() + +# Perform compiler test with a static library +set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY) + +set(CMAKE_C_COMPILER ${ARM_TOOLCHAIN_PATH}/${TARGET_TRIPLET}gcc${TOOLCHAIN_EXT}) +set(CMAKE_CXX_COMPILER ${ARM_TOOLCHAIN_PATH}/${TARGET_TRIPLET}g++${TOOLCHAIN_EXT}) +set(CMAKE_ASM_COMPILER ${ARM_TOOLCHAIN_PATH}/${TARGET_TRIPLET}gcc${TOOLCHAIN_EXT}) +set(CMAKE_LINKER ${ARM_TOOLCHAIN_PATH}/${TARGET_TRIPLET}gcc${TOOLCHAIN_EXT}) +set(CMAKE_SIZE_UTIL ${ARM_TOOLCHAIN_PATH}/${TARGET_TRIPLET}size${TOOLCHAIN_EXT}) +set(CMAKE_OBJCOPY ${ARM_TOOLCHAIN_PATH}/${TARGET_TRIPLET}objcopy${TOOLCHAIN_EXT}) +set(CMAKE_OBJDUMP ${ARM_TOOLCHAIN_PATH}/${TARGET_TRIPLET}objdump${TOOLCHAIN_EXT}) +set(CMAKE_NM_UTIL ${ARM_TOOLCHAIN_PATH}/${TARGET_TRIPLET}gcc-nm${TOOLCHAIN_EXT}) +set(CMAKE_AR ${ARM_TOOLCHAIN_PATH}/${TARGET_TRIPLET}gcc-ar${TOOLCHAIN_EXT}) +set(CMAKE_RANLIB ${ARM_TOOLCHAIN_PATH}/${TARGET_TRIPLET}gcc-ranlib${TOOLCHAIN_EXT}) + +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) + +# Compiler and linker flags +set(CMAKE_COMMON_FLAGS "-g3 -ffunction-sections -fdata-sections -fno-strict-aliasing -fno-builtin -fno-common -Wall -Wdouble-promotion -Werror -Wno-unused-parameter") +set(CMAKE_C_FLAGS "${MCPU_FLAGS} ${VFP_FLAGS} ${CMAKE_COMMON_FLAGS}") +set(CMAKE_CXX_FLAGS "${MCPU_FLAGS} ${VFP_FLAGS} ${CMAKE_COMMON_FLAGS}") +set(CMAKE_ASM_FLAGS "${MCPU_FLAGS} ${VFP_FLAGS} ${CMAKE_COMMON_FLAGS}") +set(CMAKE_EXE_LINKER_FLAGS "${LD_FLAGS} --specs=nano.specs -Wl,--gc-sections,-print-memory-usage") + +set(CMAKE_C_FLAGS_DEBUG "-O0") +set(CMAKE_CXX_FLAGS_DEBUG "-O0") +set(CMAKE_ASM_FLAGS_DEBUG "") +set(CMAKE_EXE_LINKER_FLAGS_DEBUG "") + +set(CMAKE_C_FLAGS_RELEASE "-Os -flto") +set(CMAKE_CXX_FLAGS_RELEASE "-Os -flto") +set(CMAKE_ASM_FLAGS_RELEASE "") +set(CMAKE_EXE_LINKER_FLAGS_RELEASE "-flto") diff --git a/NXP/MIMXRT1064-EVK/cmake/utilities.cmake b/NXP/MIMXRT1064-EVK/cmake/utilities.cmake new file mode 100644 index 00000000..b86454da --- /dev/null +++ b/NXP/MIMXRT1064-EVK/cmake/utilities.cmake @@ -0,0 +1,50 @@ +# Copyright (c) Microsoft +# Copyright (c) 2026 Eclipse ThreadX contributors +# +# 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: +# Microsoft - Initial version +# Frédéric Desbiens - 2024 version. +# Ali Eissa - 2026 version. + +function(post_build TARGET) + if(CMAKE_C_COMPILER_ID STREQUAL "IAR") + add_custom_target(${TARGET}.bin ALL + DEPENDS ${TARGET} + COMMAND ${CMAKE_IAR_ELFTOOL} --bin ${TARGET}.elf ${TARGET}.bin) + elseif(CMAKE_C_COMPILER_ID STREQUAL "GNU") + add_custom_target(${TARGET}.bin ALL + DEPENDS ${TARGET} + COMMAND ${CMAKE_OBJCOPY} -Obinary ${TARGET}.elf ${TARGET}.bin + COMMAND ${CMAKE_OBJCOPY} -Oihex ${TARGET}.elf ${TARGET}.hex) + else() + message(FATAL_ERROR "Unknown CMAKE_C_COMPILER_ID ${CMAKE_C_COMPILER_ID}") + endif() +endfunction() + +function(set_target_linker TARGET LINKER_SCRIPT) + if(CMAKE_C_COMPILER_ID STREQUAL "IAR") + target_link_options(${TARGET} PRIVATE --config ${LINKER_SCRIPT}) + target_link_options(${TARGET} PRIVATE --map=${TARGET}.map) + elseif(CMAKE_C_COMPILER_ID STREQUAL "GNU") + target_link_options(${TARGET} PRIVATE -T${LINKER_SCRIPT}) + target_link_options(${TARGET} PRIVATE -Wl,-Map=${TARGET}.map) + set_target_properties(${TARGET} PROPERTIES SUFFIX ".elf") + else() + message(FATAL_ERROR "Unknown CMAKE_C_COMPILER_ID ${CMAKE_C_COMPILER_ID}") + endif() +endfunction() + +macro(print_all_variables) + message(STATUS "print_all_variables------------------------------------------{") + get_cmake_property(_variableNames VARIABLES) + foreach (_variableName ${_variableNames}) + message(STATUS "${_variableName}=${${_variableName}}") + endforeach() + message(STATUS "print_all_variables------------------------------------------}") +endmacro() diff --git a/NXP/MIMXRT1064-EVK/lib/threadx/tx_user.h b/NXP/MIMXRT1064-EVK/lib/threadx/tx_user.h new file mode 100644 index 00000000..c9258245 --- /dev/null +++ b/NXP/MIMXRT1064-EVK/lib/threadx/tx_user.h @@ -0,0 +1,26 @@ +/**************************************************************************/ +/* Copyright (c) Microsoft */ +/* Copyright (c) 2026 Eclipse ThreadX contributors */ +/* */ +/* 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. */ +/**************************************************************************/ + +#ifndef TX_USER_H +#define TX_USER_H + +/* Enable hardware FPU register context switching support for Cortex-M7 */ +#define TX_ENABLE_FPU_SUPPORT + +/* System tick frequency in Hz (typically 100 or 1000) */ +#ifndef TX_TIMER_TICKS_PER_SECOND +#define TX_TIMER_TICKS_PER_SECOND 1000 +#endif + +#endif /* TX_USER_H */ diff --git a/NXP/MIMXRT1064-EVK/scripts/build.ps1 b/NXP/MIMXRT1064-EVK/scripts/build.ps1 new file mode 100644 index 00000000..e688610d --- /dev/null +++ b/NXP/MIMXRT1064-EVK/scripts/build.ps1 @@ -0,0 +1,84 @@ +# Copyright (c) 2026 Eclipse ThreadX contributors +# +# 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. + +param( + [switch]$Clean, + [switch]$Rebuild +) + +$BoardDir = Resolve-Path "$PSScriptRoot/.." +$BUILD_DIR = Join-Path $BoardDir "build" +$NUM_JOBS = 4 + +Write-Host "==========================================" +Write-Host "NXP MIMXRT1064-EVK - Build Script" +Write-Host "==========================================" +Write-Host "Board Dir: $BoardDir" +Write-Host "Build Dir: $BUILD_DIR" +Write-Host "" + +# Check for ARM GCC compiler +$armGcc = Get-Command "arm-none-eabi-gcc" -ErrorAction SilentlyContinue +if (!$armGcc -and !$env:ARM_GCC_PATH) { + Write-Host "[WARNING] arm-none-eabi-gcc not found on PATH and ARM_GCC_PATH not set." -ForegroundColor Yellow + Write-Host "" +} + +if ($Clean -or $Rebuild) { + Write-Host "[INFO] Cleaning build directory..." + if (Test-Path $BUILD_DIR) { + Remove-Item -Path $BUILD_DIR -Recurse -Force + } + New-Item -ItemType Directory -Path $BUILD_DIR -Force | Out-Null + Write-Host "[OK] Build directory cleaned" + Write-Host "" +} + +if (!(Test-Path $BUILD_DIR)) { + New-Item -ItemType Directory -Path $BUILD_DIR -Force | Out-Null +} + +Push-Location $BUILD_DIR + +# Reconfigure if CMakeCache.txt or build.ninja is missing, or if forced +if (!(Test-Path "CMakeCache.txt") -or !(Test-Path "build.ninja") -or $Rebuild) { + Write-Host "[INFO] Configuring CMake..." + cmake -G Ninja ` + "-DCMAKE_BUILD_TYPE=Release" ` + .. + if ($LASTEXITCODE -ne 0) { + Write-Host "[ERROR] CMake configuration failed!" -ForegroundColor Red + Pop-Location + exit 1 + } + Write-Host "[OK] CMake configured" + Write-Host "" +} + +Write-Host "[INFO] Building with $NUM_JOBS parallel jobs..." +if (Get-Command ninja -ErrorAction SilentlyContinue) { + ninja -j $NUM_JOBS +} else { + cmake --build . --parallel $NUM_JOBS --config Release +} + +$buildExitCode = $LASTEXITCODE +Pop-Location + +if ($buildExitCode -ne 0) { + Write-Host "[ERROR] Build failed!" -ForegroundColor Red + exit 1 +} + +Write-Host "" +Write-Host "==========================================" +Write-Host "[OK] Build completed successfully!" +Write-Host "==========================================" diff --git a/NXP/MIMXRT1064-EVK/scripts/build.sh b/NXP/MIMXRT1064-EVK/scripts/build.sh new file mode 100644 index 00000000..a202f82f --- /dev/null +++ b/NXP/MIMXRT1064-EVK/scripts/build.sh @@ -0,0 +1,77 @@ +#!/usr/bin/env bash +# Copyright (c) 2026 Eclipse ThreadX contributors +# +# 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. + +set -e + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +BOARD_DIR="$(cd "${SCRIPT_DIR}/.." && pwd)" +BUILD_DIR="${BOARD_DIR}/build" +NUM_JOBS=4 + +CLEAN=0 +REBUILD=0 + +# Parse arguments +while [[ "$#" -gt 0 ]]; do + case $1 in + --clean) CLEAN=1 ;; + --rebuild) REBUILD=1 ;; + *) echo "Unknown parameter passed: $1"; exit 1 ;; + esac + shift +done + +echo "==========================================" +echo "NXP MIMXRT1064-EVK - Build Script (POSIX)" +echo "==========================================" +echo "Board Dir: ${BOARD_DIR}" +echo "Build Dir: ${BUILD_DIR}" +echo "" + +# Check for ARM GCC compiler +if ! command -v arm-none-eabi-gcc &> /dev/null && [ -z "${ARM_GCC_PATH}" ]; then + echo "[WARNING] arm-none-eabi-gcc not found on PATH and ARM_GCC_PATH not set." + echo "" +fi + +if [ "${CLEAN}" -eq 1 ] || [ "${REBUILD}" -eq 1 ]; then + echo "[INFO] Cleaning build directory..." + rm -rf "${BUILD_DIR}" + mkdir -p "${BUILD_DIR}" + echo "[OK] Build directory cleaned" + echo "" +fi + +mkdir -p "${BUILD_DIR}" +cd "${BUILD_DIR}" + +# Reconfigure if CMakeCache.txt or build.ninja is missing, or if forced +if [ ! -f "CMakeCache.txt" ] || [ ! -f "build.ninja" ] || [ "${REBUILD}" -eq 1 ]; then + echo "[INFO] Configuring CMake..." + cmake -G Ninja \ + -DCMAKE_BUILD_TYPE=Release \ + .. + echo "[OK] CMake configured" + echo "" +fi + +echo "[INFO] Building with ${NUM_JOBS} parallel jobs..." +if command -v ninja &> /dev/null; then + ninja -j "${NUM_JOBS}" +else + cmake --build . --parallel "${NUM_JOBS}" --config Release +fi + +echo "" +echo "==========================================" +echo "[OK] Build completed successfully!" +echo "==========================================" diff --git a/NXP/MIMXRT1064-EVK/scripts/fetch_sdk.ps1 b/NXP/MIMXRT1064-EVK/scripts/fetch_sdk.ps1 new file mode 100644 index 00000000..8965cb87 --- /dev/null +++ b/NXP/MIMXRT1064-EVK/scripts/fetch_sdk.ps1 @@ -0,0 +1,169 @@ +# Copyright (c) 2026 Eclipse ThreadX contributors +# +# 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. + +$BoardDir = Resolve-Path "$PSScriptRoot/.." +$LibDir = Join-Path $BoardDir "lib/mcux-sdk" +$DeviceDir = Join-Path $LibDir "devices/MIMXRT1064" +$DriversDir = Join-Path $LibDir "drivers" +$UtilitiesDir = Join-Path $LibDir "utilities" +$ComponentsDir = Join-Path $LibDir "components" +$BoardFilesDir = Join-Path $LibDir "board" +$CmsisIncludeDest = Join-Path $LibDir "CMSIS/Include" +$TempDir = Join-Path $BoardDir "temp_fetch" + +Write-Host "==========================================" +Write-Host "NXP i.MX RT1064 Standalone Driver Fetcher" +Write-Host "==========================================" +Write-Host "Target Directory: $LibDir" +Write-Host "" + +# Clean and create target directories +if (Test-Path $LibDir) { Remove-Item -Path $LibDir -Recurse -Force } +New-Item -ItemType Directory -Path $DeviceDir -Force | Out-Null +New-Item -ItemType Directory -Path $DriversDir -Force | Out-Null +New-Item -ItemType Directory -Path $UtilitiesDir -Force | Out-Null +New-Item -ItemType Directory -Path (Join-Path $ComponentsDir "uart") -Force | Out-Null +New-Item -ItemType Directory -Path $BoardFilesDir -Force | Out-Null +New-Item -ItemType Directory -Path $CmsisIncludeDest -Force | Out-Null + +if (Test-Path $TempDir) { Remove-Item -Path $TempDir -Recurse -Force } +New-Item -ItemType Directory -Path $TempDir -Force | Out-Null + +function Clean-Temp { + if (Test-Path $TempDir) { + Remove-Item -Path $TempDir -Recurse -Force + } +} + +try { + # 1. Download official NXP MIMXRT1064 DFP pack from NXP repository + $packUrl = "https://mcuxpresso.nxp.com/cmsis_pack/repo/NXP.MIMXRT1064_DFP.15.1.0.pack" + $packZip = Join-Path $TempDir "dfp.zip" + $packExtract = Join-Path $TempDir "dfp_extracted" + + Write-Host "[INFO] Downloading official NXP MIMXRT1064 Device Pack..." + [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 + Invoke-WebRequest -Uri $packUrl -OutFile $packZip -UseBasicParsing + + Write-Host "[INFO] Extracting Device Pack..." + Expand-Archive -Path $packZip -DestinationPath $packExtract -Force + + # Copy device register headers & system files + $deviceFiles = @( + "MIMXRT1064.h", + "MIMXRT1064_features.h", + "fsl_device_registers.h", + "system_MIMXRT1064.c", + "system_MIMXRT1064.h" + ) + foreach ($file in $deviceFiles) { + $source = Join-Path $packExtract $file + if (Test-Path $source) { + Copy-Item -Path $source -Destination $DeviceDir -Force + } + } + + # Copy core peripheral drivers + $driverList = @( + "fsl_clock.c", "fsl_clock.h", + "fsl_common.c", "fsl_common.h", + "fsl_common_arm.c", "fsl_common_arm.h", + "fsl_gpio.c", "fsl_gpio.h", + "fsl_lpuart.c", "fsl_lpuart.h", + "fsl_enet.c", "fsl_enet.h", + "fsl_iomuxc.h" + ) + foreach ($file in $driverList) { + $source = Join-Path $packExtract "drivers/$file" + if (Test-Path $source) { + Copy-Item -Path $source -Destination $DriversDir -Force + } + } + + # Copy utilities (debug console & string formatting) + $utilFiles = @( + "utilities/debug_console_lite/fsl_debug_console.h", + "utilities/debug_console_lite/fsl_debug_console.c", + "utilities/debug_console_lite/fsl_assert.c", + "utilities/debug_console/fsl_debug_console_conf.h", + "utilities/str/fsl_str.c", + "utilities/str/fsl_str.h" + ) + foreach ($file in $utilFiles) { + $source = Join-Path $packExtract $file + if (Test-Path $source) { + Copy-Item -Path $source -Destination $UtilitiesDir -Force + } + } + + # Copy UART component adapter + $compUartDest = Join-Path $ComponentsDir "uart" + $compUartFiles = @( + "components/uart/fsl_adapter_uart.h", + "components/uart/fsl_adapter_lpuart.c" + ) + foreach ($file in $compUartFiles) { + $source = Join-Path $packExtract $file + if (Test-Path $source) { + Copy-Item -Path $source -Destination $compUartDest -Force + } + } + + # Copy XIP flexspi boot header from pack + $xipSource = Join-Path $packExtract "xip" + if (Test-Path $xipSource) { + Copy-Item -Path "$xipSource/*" -Destination $DeviceDir -Recurse -Force + } + Write-Host "[OK] NXP Device, Driver, Utility, and Component files copied" + Write-Host "" + + # 2. Download EVK-MIMXRT1064 Board Initialization Files from official NXP mcuxsdk-examples + $rawBase = "https://raw.githubusercontent.com/nxp-mcuxpresso/mcuxsdk-examples/main/_boards/evkmimxrt1064" + $boardFiles = @( + @{ Remote = "$rawBase/board.c"; Local = "board.c" }, + @{ Remote = "$rawBase/board.h"; Local = "board.h" }, + @{ Remote = "$rawBase/project_template/clock_config.c"; Local = "clock_config.c" }, + @{ Remote = "$rawBase/project_template/clock_config.h"; Local = "clock_config.h" }, + @{ Remote = "$rawBase/project_template/pin_mux.c"; Local = "pin_mux.c" }, + @{ Remote = "$rawBase/project_template/pin_mux.h"; Local = "pin_mux.h" }, + @{ Remote = "$rawBase/dcd.c"; Local = "dcd.c" }, + @{ Remote = "$rawBase/dcd.h"; Local = "dcd.h" }, + @{ Remote = "$rawBase/xip/evkmimxrt1064_flexspi_nor_config.c"; Local = "evkmimxrt1064_flexspi_nor_config.c" }, + @{ Remote = "$rawBase/xip/evkmimxrt1064_flexspi_nor_config.h"; Local = "evkmimxrt1064_flexspi_nor_config.h" }, + @{ Remote = "$rawBase/linker/mcux/MIMXRT1064xxxxx_flexspi_nor.ld"; Local = "MIMXRT1064xxxxx_flexspi_nor.ld" } + ) + + Write-Host "[INFO] Downloading EVK-MIMXRT1064 board support files..." + foreach ($item in $boardFiles) { + $dest = Join-Path $BoardFilesDir $item.Local + Invoke-WebRequest -Uri $item.Remote -OutFile $dest -UseBasicParsing + } + Write-Host "[OK] Board support files downloaded" + Write-Host "" + + # 3. Fetch CMSIS Core headers (standard ARM CMSIS-Core include files) + Write-Host "[INFO] Cloning CMSIS Core headers (depth=1)..." + $cmsisCloneDir = Join-Path $TempDir "cmsis_core_repo" + git clone --depth 1 https://github.com/STMicroelectronics/cmsis-core.git $cmsisCloneDir + if ($LASTEXITCODE -ne 0) { + throw "Failed to clone CMSIS Core repository" + } + Copy-Item -Path "$cmsisCloneDir/CMSIS/Core/Include/*" -Destination $CmsisIncludeDest -Recurse -Force + Write-Host "[OK] CMSIS Core headers copied" + Write-Host "" + + Write-Host "==========================================" + Write-Host "[SUCCESS] NXP i.MX RT1064 drivers successfully fetched!" + Write-Host "==========================================" +} +finally { + Clean-Temp +} diff --git a/NXP/MIMXRT1064-EVK/scripts/fetch_sdk.sh b/NXP/MIMXRT1064-EVK/scripts/fetch_sdk.sh new file mode 100644 index 00000000..50f2c45c --- /dev/null +++ b/NXP/MIMXRT1064-EVK/scripts/fetch_sdk.sh @@ -0,0 +1,128 @@ +#!/usr/bin/env bash +# Copyright (c) 2026 Eclipse ThreadX contributors +# +# 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. + +set -e + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +BOARD_DIR="$(cd "${SCRIPT_DIR}/.." && pwd)" + +LIB_DIR="${BOARD_DIR}/lib/mcux-sdk" +DEVICE_DIR="${LIB_DIR}/devices/MIMXRT1064" +DRIVERS_DIR="${LIB_DIR}/drivers" +UTILITIES_DIR="${LIB_DIR}/utilities" +COMPONENTS_DIR="${LIB_DIR}/components" +BOARD_FILES_DIR="${LIB_DIR}/board" +CMSIS_INCLUDE_DEST="${LIB_DIR}/CMSIS/Include" +TEMP_DIR="${BOARD_DIR}/temp_fetch" + +echo "==========================================" +echo "NXP i.MX RT1064 Standalone Driver Fetcher (POSIX)" +echo "==========================================" +echo "Target Directory: ${LIB_DIR}" +echo "" + +# Clean and recreate directories +rm -rf "${LIB_DIR}" +mkdir -p "${DEVICE_DIR}" +mkdir -p "${DRIVERS_DIR}" +mkdir -p "${UTILITIES_DIR}" +mkdir -p "${COMPONENTS_DIR}/uart" +mkdir -p "${BOARD_FILES_DIR}" +mkdir -p "${CMSIS_INCLUDE_DEST}" + +rm -rf "${TEMP_DIR}" +mkdir -p "${TEMP_DIR}" + +clean_temp() { + if [ -d "${TEMP_DIR}" ]; then + rm -rf "${TEMP_DIR}" + fi +} +trap clean_temp EXIT + +# 1. Download official NXP MIMXRT1064 DFP pack from NXP repository +PACK_URL="https://mcuxpresso.nxp.com/cmsis_pack/repo/NXP.MIMXRT1064_DFP.15.1.0.pack" +PACK_ZIP="${TEMP_DIR}/dfp.zip" +PACK_EXTRACT="${TEMP_DIR}/dfp_extracted" + +echo "[INFO] Downloading official NXP MIMXRT1064 Device Pack..." +curl -fsSL "${PACK_URL}" -o "${PACK_ZIP}" + +echo "[INFO] Extracting Device Pack..." +mkdir -p "${PACK_EXTRACT}" +unzip -q "${PACK_ZIP}" -d "${PACK_EXTRACT}" + +# Copy device register headers & system files +for file in MIMXRT1064.h MIMXRT1064_features.h fsl_device_registers.h system_MIMXRT1064.c system_MIMXRT1064.h; do + if [ -f "${PACK_EXTRACT}/${file}" ]; then + cp "${PACK_EXTRACT}/${file}" "${DEVICE_DIR}/" + fi +done + +# Copy core peripheral drivers +for file in fsl_clock.c fsl_clock.h fsl_common.c fsl_common.h fsl_common_arm.c fsl_common_arm.h fsl_gpio.c fsl_gpio.h fsl_lpuart.c fsl_lpuart.h fsl_enet.c fsl_enet.h fsl_iomuxc.h; do + if [ -f "${PACK_EXTRACT}/drivers/${file}" ]; then + cp "${PACK_EXTRACT}/drivers/${file}" "${DRIVERS_DIR}/" + fi +done + +# Copy utilities (debug console & string formatting) +for file in utilities/debug_console_lite/fsl_debug_console.h utilities/debug_console_lite/fsl_debug_console.c utilities/debug_console_lite/fsl_assert.c utilities/debug_console/fsl_debug_console_conf.h utilities/str/fsl_str.c utilities/str/fsl_str.h; do + if [ -f "${PACK_EXTRACT}/${file}" ]; then + cp "${PACK_EXTRACT}/${file}" "${UTILITIES_DIR}/" + fi +done + +# Copy UART component adapter +for file in components/uart/fsl_adapter_uart.h components/uart/fsl_adapter_lpuart.c; do + if [ -f "${PACK_EXTRACT}/${file}" ]; then + cp "${PACK_EXTRACT}/${file}" "${COMPONENTS_DIR}/uart/" + fi +done + +# Copy XIP flexspi boot headers +if [ -d "${PACK_EXTRACT}/xip" ]; then + cp -r "${PACK_EXTRACT}/xip/"* "${DEVICE_DIR}/" +fi +echo "[OK] NXP Device, Driver, Utility, and Component files copied" +echo "" + +# 2. Download EVK-MIMXRT1064 Board Support Files from official NXP mcuxsdk-examples +RAW_BASE="https://raw.githubusercontent.com/nxp-mcuxpresso/mcuxsdk-examples/main/_boards/evkmimxrt1064" +echo "[INFO] Downloading EVK-MIMXRT1064 board support files..." + +curl -fsSL "${RAW_BASE}/board.c" -o "${BOARD_FILES_DIR}/board.c" +curl -fsSL "${RAW_BASE}/board.h" -o "${BOARD_FILES_DIR}/board.h" +curl -fsSL "${RAW_BASE}/project_template/clock_config.c" -o "${BOARD_FILES_DIR}/clock_config.c" +curl -fsSL "${RAW_BASE}/project_template/clock_config.h" -o "${BOARD_FILES_DIR}/clock_config.h" +curl -fsSL "${RAW_BASE}/project_template/pin_mux.c" -o "${BOARD_FILES_DIR}/pin_mux.c" +curl -fsSL "${RAW_BASE}/project_template/pin_mux.h" -o "${BOARD_FILES_DIR}/pin_mux.h" +curl -fsSL "${RAW_BASE}/dcd.c" -o "${BOARD_FILES_DIR}/dcd.c" +curl -fsSL "${RAW_BASE}/dcd.h" -o "${BOARD_FILES_DIR}/dcd.h" +curl -fsSL "${RAW_BASE}/xip/evkmimxrt1064_flexspi_nor_config.c" -o "${BOARD_FILES_DIR}/evkmimxrt1064_flexspi_nor_config.c" +curl -fsSL "${RAW_BASE}/xip/evkmimxrt1064_flexspi_nor_config.h" -o "${BOARD_FILES_DIR}/evkmimxrt1064_flexspi_nor_config.h" +curl -fsSL "${RAW_BASE}/linker/mcux/MIMXRT1064xxxxx_flexspi_nor.ld" -o "${BOARD_FILES_DIR}/MIMXRT1064xxxxx_flexspi_nor.ld" + +echo "[OK] Board support files downloaded" +echo "" + +# 3. Fetch CMSIS Core headers +echo "[INFO] Cloning CMSIS Core headers (depth=1)..." +CMSIS_CLONE_DIR="${TEMP_DIR}/cmsis_core_repo" +git clone --depth 1 https://github.com/STMicroelectronics/cmsis-core.git "${CMSIS_CLONE_DIR}" +cp -r "${CMSIS_CLONE_DIR}/CMSIS/Core/Include/"* "${CMSIS_INCLUDE_DEST}/" +echo "[OK] CMSIS Core headers copied" +echo "" + +echo "==========================================" +echo "[SUCCESS] NXP i.MX RT1064 drivers successfully fetched!" +echo "==========================================" From d3b2af9865aa23d428f244002dff4ab47b668664 Mon Sep 17 00:00:00 2001 From: Ali Eissa Date: Thu, 10 Sep 2026 06:55:45 +0400 Subject: [PATCH 02/11] Bring up core ThreadX kernel on MIMXRT1064-EVK Signed-off-by: Ali Eissa Assisted-by: Google DeepMind Antigravity --- NXP/MIMXRT1064-EVK/CMakeLists.txt | 52 + NXP/MIMXRT1064-EVK/app/board_init.c | 33 + NXP/MIMXRT1064-EVK/app/board_init.h | 32 + NXP/MIMXRT1064-EVK/app/console.c | 87 ++ NXP/MIMXRT1064-EVK/app/console.h | 34 + NXP/MIMXRT1064-EVK/app/main.c | 158 +++ .../startup/MIMXRT1064xxxxx_flexspi_nor.ld | 276 ++++ .../app/startup/startup_mimxrt1064.S | 1146 +++++++++++++++++ .../app/startup/tx_initialize_low_level.S | 207 +++ NXP/MIMXRT1064-EVK/app/syscalls.c | 131 ++ NXP/MIMXRT1064-EVK/app/sysmem.c | 50 + NXP/MIMXRT1064-EVK/lib/threadx/tx_user.h | 2 +- NXP/MIMXRT1064-EVK/renode/mimxrt1064-evk.resc | 21 + NXP/MIMXRT1064-EVK/scripts/fetch_sdk.ps1 | 37 +- NXP/MIMXRT1064-EVK/scripts/fetch_sdk.sh | 12 +- NXP/MIMXRT1064-EVK/scripts/simulate.ps1 | 47 + NXP/MIMXRT1064-EVK/scripts/simulate.sh | 43 + 17 files changed, 2361 insertions(+), 7 deletions(-) create mode 100644 NXP/MIMXRT1064-EVK/app/board_init.c create mode 100644 NXP/MIMXRT1064-EVK/app/board_init.h create mode 100644 NXP/MIMXRT1064-EVK/app/console.c create mode 100644 NXP/MIMXRT1064-EVK/app/console.h create mode 100644 NXP/MIMXRT1064-EVK/app/main.c create mode 100644 NXP/MIMXRT1064-EVK/app/startup/MIMXRT1064xxxxx_flexspi_nor.ld create mode 100644 NXP/MIMXRT1064-EVK/app/startup/startup_mimxrt1064.S create mode 100644 NXP/MIMXRT1064-EVK/app/startup/tx_initialize_low_level.S create mode 100644 NXP/MIMXRT1064-EVK/app/syscalls.c create mode 100644 NXP/MIMXRT1064-EVK/app/sysmem.c create mode 100644 NXP/MIMXRT1064-EVK/renode/mimxrt1064-evk.resc create mode 100644 NXP/MIMXRT1064-EVK/scripts/simulate.ps1 create mode 100644 NXP/MIMXRT1064-EVK/scripts/simulate.sh diff --git a/NXP/MIMXRT1064-EVK/CMakeLists.txt b/NXP/MIMXRT1064-EVK/CMakeLists.txt index 66d6593d..69036528 100644 --- a/NXP/MIMXRT1064-EVK/CMakeLists.txt +++ b/NXP/MIMXRT1064-EVK/CMakeLists.txt @@ -82,3 +82,55 @@ target_include_directories(${SDK_TARGET} # Compile ThreadX Kernel from root shared libs submodule set(THREADX_DIR "${CMAKE_CURRENT_LIST_DIR}/../../libs/threadx") add_subdirectory(${THREADX_DIR} threadx) + +# Create the Main Executable +set(EXE_TARGET mimxrt1064_threadx) + +add_executable(${EXE_TARGET} + app/startup/startup_mimxrt1064.S + app/startup/tx_initialize_low_level.S + app/board_init.c + app/console.c + app/main.c + app/sysmem.c + app/syscalls.c +) + +# Set compile definitions for our executable +target_compile_definitions(${EXE_TARGET} + PRIVATE + 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 +) + +# Include paths +target_include_directories(${EXE_TARGET} + PRIVATE + ${CMAKE_CURRENT_LIST_DIR}/app + ${SDK_DIR}/CMSIS/Include + ${SDK_DIR}/devices/MIMXRT1064 + ${SDK_DIR}/drivers + ${SDK_DIR}/board + ${SDK_DIR}/utilities + ${SDK_DIR}/components/uart + ${TX_USER_FILE_DIR} +) + +# Link libraries (includes ThreadX kernel and MCUXpresso SDK object libraries) +target_link_libraries(${EXE_TARGET} + PRIVATE + threadx + mcux_sdk +) + +# Apply GCC linker script and print memory usage (utilities.cmake function) +set_target_linker(${EXE_TARGET} "${CMAKE_CURRENT_LIST_DIR}/app/startup/MIMXRT1064xxxxx_flexspi_nor.ld") + +# Post-build commands to generate raw .bin and .hex files +post_build(${EXE_TARGET}) + diff --git a/NXP/MIMXRT1064-EVK/app/board_init.c b/NXP/MIMXRT1064-EVK/app/board_init.c new file mode 100644 index 00000000..9586e39c --- /dev/null +++ b/NXP/MIMXRT1064-EVK/app/board_init.c @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2026 Eclipse ThreadX contributors + * + * 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 NXP i.MX RT1064 port. + */ + +#include "board_init.h" +#include "console.h" + +void board_init(void) +{ + /* 1. Configure the Memory Protection Unit if supported by hardware (16 regions on real Cortex-M7 silicon) */ + if (((MPU->TYPE & MPU_TYPE_DREGION_Msk) >> MPU_TYPE_DREGION_Pos) >= 12) + { + BOARD_ConfigMPU(); + } + + /* 2. Configure Pin Muxing (UART1 TX/RX pins) */ + BOARD_InitPins(); + + /* 3. Configure System Clocks (600 MHz AHB core clock) */ + BOARD_BootClockRUN(); + + /* 4. Initialize LPUART1 Serial Console at 115200 baud */ + console_init(); +} diff --git a/NXP/MIMXRT1064-EVK/app/board_init.h b/NXP/MIMXRT1064-EVK/app/board_init.h new file mode 100644 index 00000000..3080890b --- /dev/null +++ b/NXP/MIMXRT1064-EVK/app/board_init.h @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2026 Eclipse ThreadX contributors + * + * 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 NXP i.MX RT1064 port. + */ + +#ifndef BOARD_INIT_H +#define BOARD_INIT_H + +#include "fsl_common.h" +#include "board.h" +#include "pin_mux.h" +#include "clock_config.h" + +#ifdef __cplusplus +extern "C" { +#endif + +void board_init(void); + +#ifdef __cplusplus +} +#endif + +#endif /* BOARD_INIT_H */ diff --git a/NXP/MIMXRT1064-EVK/app/console.c b/NXP/MIMXRT1064-EVK/app/console.c new file mode 100644 index 00000000..9c95756f --- /dev/null +++ b/NXP/MIMXRT1064-EVK/app/console.c @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2026 Eclipse ThreadX contributors + * + * 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 NXP i.MX RT1064 port. + */ + +#include "console.h" +#include "fsl_lpuart.h" +#include "board.h" + +void console_init(void) +{ + lpuart_config_t config; + + LPUART_GetDefaultConfig(&config); + config.baudRate_Bps = 115200U; + config.enableTx = true; + config.enableRx = true; + + uint32_t uartClkSrcFreq = BOARD_DebugConsoleSrcFreq(); + LPUART_Init(LPUART1, &config, uartClkSrcFreq); +} + +void console_putc(char c) +{ + if (c == '\n') + { + while (!(LPUART_GetStatusFlags(LPUART1) & (uint32_t)kLPUART_TxDataRegEmptyFlag)) + { + } + LPUART_WriteByte(LPUART1, (uint8_t)'\r'); + } + + while (!(LPUART_GetStatusFlags(LPUART1) & (uint32_t)kLPUART_TxDataRegEmptyFlag)) + { + } + LPUART_WriteByte(LPUART1, (uint8_t)c); +} + +void console_write(const char *str) +{ + while (*str != '\0') + { + console_putc(*str++); + } +} + +int __io_putchar(int ch) +{ + console_putc((char)ch); + return ch; +} + +int __io_getchar(void) +{ + while (!(LPUART_GetStatusFlags(LPUART1) & (uint32_t)kLPUART_RxDataRegFullFlag)) + { + } + return (int)LPUART_ReadByte(LPUART1); +} + +int _write(int file, char *ptr, int len) +{ + (void)file; + for (int i = 0; i < len; i++) + { + console_putc(ptr[i]); + } + return len; +} + +int _read(int file, char *ptr, int len) +{ + (void)file; + for (int i = 0; i < len; i++) + { + ptr[i] = (char)__io_getchar(); + } + return len; +} diff --git a/NXP/MIMXRT1064-EVK/app/console.h b/NXP/MIMXRT1064-EVK/app/console.h new file mode 100644 index 00000000..89140a90 --- /dev/null +++ b/NXP/MIMXRT1064-EVK/app/console.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2026 Eclipse ThreadX contributors + * + * 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 NXP i.MX RT1064 port. + */ + +#ifndef CONSOLE_H +#define CONSOLE_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +void console_init(void); +void console_putc(char c); +void console_write(const char *str); +int __io_putchar(int ch); +int __io_getchar(void); + +#ifdef __cplusplus +} +#endif + +#endif /* CONSOLE_H */ diff --git a/NXP/MIMXRT1064-EVK/app/main.c b/NXP/MIMXRT1064-EVK/app/main.c new file mode 100644 index 00000000..c3807225 --- /dev/null +++ b/NXP/MIMXRT1064-EVK/app/main.c @@ -0,0 +1,158 @@ +/* + * Copyright (c) 2026 Eclipse ThreadX contributors + * + * 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 NXP i.MX RT1064 port. + */ + +#include "board_init.h" +#include "console.h" +#include "tx_api.h" +#include + +#define HEARTBEAT_THREAD_STACK_SIZE 1024 +#define WORKER_THREAD_STACK_SIZE 1024 + +static TX_THREAD heartbeat_thread; +static uint8_t heartbeat_thread_stack[HEARTBEAT_THREAD_STACK_SIZE]; + +static TX_THREAD worker_thread; +static uint8_t worker_thread_stack[WORKER_THREAD_STACK_SIZE]; + +static TX_TIMER app_timer; +static volatile ULONG timer_fire_count = 0; + +/* Thread Function Prototypes */ +static void heartbeat_thread_entry(ULONG thread_input); +static void worker_thread_entry(ULONG thread_input); +static void app_timer_callback(ULONG timer_input); + +int main(void) +{ + /* Initialize hardware: MPU, clocks (600 MHz), pins, and LPUART1 */ + board_init(); + + printf("\r\n"); + printf("==================================================\r\n"); + printf(" Eclipse ThreadX RTOS on NXP i.MX RT1064-EVK\r\n"); + printf(" Simulated in Antmicro Renode\r\n"); + printf("==================================================\r\n"); + printf("[System] Core Clock: %lu MHz | Tick Rate: %u Hz\r\n", + SystemCoreClock / 1000000UL, + TX_TIMER_TICKS_PER_SECOND); + printf("[System] Initializing ThreadX kernel...\r\n"); + + /* Enter the ThreadX kernel */ + tx_kernel_enter(); + + return 0; +} + +void tx_application_define(void *first_unused_memory) +{ + (void)first_unused_memory; + + UINT status; + + /* Create Heartbeat Thread (Priority 15 - lower priority) */ + status = tx_thread_create(&heartbeat_thread, + "Heartbeat Thread", + heartbeat_thread_entry, + 0, + heartbeat_thread_stack, + HEARTBEAT_THREAD_STACK_SIZE, + 15, + 15, + TX_NO_TIME_SLICE, + TX_AUTO_START); + if (status != TX_SUCCESS) + { + printf("[ERROR] Failed to create Heartbeat Thread (status: 0x%02X)\r\n", status); + } + + /* Create Worker Thread (Priority 10 - medium priority) */ + status = tx_thread_create(&worker_thread, + "Worker Thread", + worker_thread_entry, + 0, + worker_thread_stack, + WORKER_THREAD_STACK_SIZE, + 10, + 10, + TX_NO_TIME_SLICE, + TX_AUTO_START); + if (status != TX_SUCCESS) + { + printf("[ERROR] Failed to create Worker Thread (status: 0x%02X)\r\n", status); + } + + /* Create Application Timer (Periodic 200 ms / 20 ticks) */ + status = tx_timer_create(&app_timer, + "App Timer", + app_timer_callback, + 0, + 20, /* Initial ticks (200 ms) */ + 20, /* Reschedule ticks (200 ms) */ + TX_AUTO_ACTIVATE); + if (status != TX_SUCCESS) + { + printf("[ERROR] Failed to create App Timer (status: 0x%02X)\r\n", status); + } + + printf("[System] ThreadX threads and timer registered successfully.\r\n"); +} + +static void heartbeat_thread_entry(ULONG thread_input) +{ + (void)thread_input; + ULONG count = 0; + + printf("[Heartbeat Thread] Started.\r\n"); + + while (1) + { + /* Sleep for 50 ticks (500 ms @ 100 Hz) */ + tx_thread_sleep(50); + count++; + + printf("[Heartbeat Thread] Heartbeat #%lu (System Tick: %lu)\r\n", + count, tx_time_get()); + } +} + +static void worker_thread_entry(ULONG thread_input) +{ + (void)thread_input; + ULONG iteration = 0; + + printf("[Worker Thread] Started.\r\n"); + + while (1) + { + /* Sleep for 100 ticks (1000 ms @ 100 Hz) */ + tx_thread_sleep(100); + iteration++; + + printf("[Worker Thread] Executing periodic task (iteration #%lu, System Tick: %lu)\r\n", + iteration, tx_time_get()); + } +} + +static void app_timer_callback(ULONG timer_input) +{ + (void)timer_input; + timer_fire_count++; + + /* Report every 5 fires (1 second) */ + if ((timer_fire_count % 5) == 0) + { + printf("[App Timer] Kernel timer callback active (total firings: %lu)\r\n", + timer_fire_count); + } +} diff --git a/NXP/MIMXRT1064-EVK/app/startup/MIMXRT1064xxxxx_flexspi_nor.ld b/NXP/MIMXRT1064-EVK/app/startup/MIMXRT1064xxxxx_flexspi_nor.ld new file mode 100644 index 00000000..e5dd1d68 --- /dev/null +++ b/NXP/MIMXRT1064-EVK/app/startup/MIMXRT1064xxxxx_flexspi_nor.ld @@ -0,0 +1,276 @@ +/* +** ################################################################### +** Processors: MIMXRT1064CVJ5A +** MIMXRT1064CVJ5B +** MIMXRT1064CVL5A +** MIMXRT1064CVL5B +** MIMXRT1064DVJ6A +** MIMXRT1064DVJ6B +** MIMXRT1064DVL6A +** MIMXRT1064DVL6B +** +** Compiler: GNU C Compiler +** Reference manual: IMXRT1064RM Rev.2, 7/2021 | IMXRT106XSRM Rev.0 +** Version: rev. 0.1, 2018-06-22 +** Build: b230821 +** +** Abstract: +** Linker file for the GNU C Compiler +** +** Copyright 2016 Freescale Semiconductor, Inc. +** Copyright 2016-2023 NXP +** SPDX-License-Identifier: BSD-3-Clause +** +** http: www.nxp.com +** mail: support@nxp.com +** +** ################################################################### +*/ + +/* Entry Point */ +ENTRY(Reset_Handler) + +HEAP_SIZE = DEFINED(__heap_size__) ? __heap_size__ : 0x0400; +STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0x0400; +VECTOR_RAM_SIZE = DEFINED(__ram_vector_table__) ? 0x00000400 : 0; + +/* Specify the memory areas */ +MEMORY +{ + m_flash_config (RX) : ORIGIN = 0x70000000, LENGTH = 0x00001000 + m_ivt (RX) : ORIGIN = 0x70001000, LENGTH = 0x00001000 + m_interrupts (RX) : ORIGIN = 0x70002000, LENGTH = 0x00000400 + m_text (RX) : ORIGIN = 0x70002400, LENGTH = 0x003FDC00 + m_qacode (RX) : ORIGIN = 0x00000000, LENGTH = 0x00020000 + m_data (RW) : ORIGIN = 0x20000000, LENGTH = 0x00020000 + m_data2 (RW) : ORIGIN = 0x20200000, LENGTH = 0x000C0000 +} + +/* Define output sections */ +SECTIONS +{ + __NCACHE_REGION_START = ORIGIN(m_data2); + __NCACHE_REGION_SIZE = 0; + + .flash_config : + { + . = ALIGN(4); + __FLASH_BASE = .; + KEEP(* (.boot_hdr.conf)) /* flash config section */ + . = ALIGN(4); + } > m_flash_config + + ivt_begin = ORIGIN(m_flash_config) + LENGTH(m_flash_config); + + .ivt : AT(ivt_begin) + { + . = ALIGN(4); + KEEP(* (.boot_hdr.ivt)) /* ivt section */ + KEEP(* (.boot_hdr.boot_data)) /* boot section */ + KEEP(* (.boot_hdr.dcd_data)) /* dcd section */ + . = ALIGN(4); + } > m_ivt + + /* The startup code goes first into internal RAM */ + .interrupts : + { + __VECTOR_TABLE = .; + __Vectors = .; + . = ALIGN(4); + KEEP(*(.isr_vector)) /* Startup code */ + . = ALIGN(4); + } > m_interrupts + + /* The program code and other data goes into internal RAM */ + .text : + { + . = ALIGN(4); + *(.text) /* .text sections (code) */ + *(.text*) /* .text* sections (code) */ + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + *(.glue_7) /* glue arm to thumb code */ + *(.glue_7t) /* glue thumb to arm code */ + *(.eh_frame) + KEEP (*(.init)) + KEEP (*(.fini)) + . = ALIGN(4); + } > m_text + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > m_text + + .ARM : + { + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + } > m_text + + .ctors : + { + __CTOR_LIST__ = .; + /* gcc uses crtbegin.o to find the start of + the constructors, so we make sure it is + first. Because this is a wildcard, it + doesn't matter if the user does not + actually link against crtbegin.o; the + linker won't look for a file to match a + wildcard. The wildcard also means that it + doesn't matter which directory crtbegin.o + is in. */ + KEEP (*crtbegin.o(.ctors)) + KEEP (*crtbegin?.o(.ctors)) + /* We don't want to include the .ctor section from + from the crtend.o file until after the sorted ctors. + The .ctor section from the crtend file contains the + end of ctors marker and it must be last */ + KEEP (*(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*(.ctors)) + __CTOR_END__ = .; + } > m_text + + .dtors : + { + __DTOR_LIST__ = .; + KEEP (*crtbegin.o(.dtors)) + KEEP (*crtbegin?.o(.dtors)) + KEEP (*(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*(.dtors)) + __DTOR_END__ = .; + } > m_text + + .preinit_array : + { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array*)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } > m_text + + .init_array : + { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array*)) + PROVIDE_HIDDEN (__init_array_end = .); + } > m_text + + .fini_array : + { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT(.fini_array.*))) + KEEP (*(.fini_array*)) + PROVIDE_HIDDEN (__fini_array_end = .); + } > m_text + + __etext = .; /* define a global symbol at end of code */ + __DATA_ROM = .; /* Symbol is used by startup for data initialization */ + + .interrupts_ram : + { + . = ALIGN(4); + __VECTOR_RAM__ = .; + __interrupts_ram_start__ = .; /* Create a global symbol at data start */ + *(.m_interrupts_ram) /* This is a user defined section */ + . += VECTOR_RAM_SIZE; + . = ALIGN(4); + __interrupts_ram_end__ = .; /* Define a global symbol at data end */ + } > m_data + + __VECTOR_RAM = DEFINED(__ram_vector_table__) ? __VECTOR_RAM__ : ORIGIN(m_interrupts); + __RAM_VECTOR_TABLE_SIZE_BYTES = DEFINED(__ram_vector_table__) ? (__interrupts_ram_end__ - __interrupts_ram_start__) : 0x0; + + .data : AT(__DATA_ROM) + { + . = ALIGN(4); + __DATA_RAM = .; + __data_start__ = .; /* create a global symbol at data start */ + *(m_usb_dma_init_data) + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + *(DataQuickAccess) /* quick access data section */ + KEEP(*(.jcr*)) + . = ALIGN(4); + __data_end__ = .; /* define a global symbol at data end */ + } > m_data + + __ram_function_flash_start = __DATA_ROM + (__data_end__ - __data_start__); /* Symbol is used by startup for TCM data initialization */ + + .ram_function : AT(__ram_function_flash_start) + { + . = ALIGN(32); + __ram_function_start__ = .; + *(CodeQuickAccess) + . = ALIGN(128); + __ram_function_end__ = .; + } > m_qacode + + __NDATA_ROM = __ram_function_flash_start + (__ram_function_end__ - __ram_function_start__); + .ncache.init : AT(__NDATA_ROM) + { + __noncachedata_start__ = .; /* create a global symbol at ncache data start */ + *(NonCacheable.init) + . = ALIGN(4); + __noncachedata_init_end__ = .; /* create a global symbol at initialized ncache data end */ + } > m_data + . = __noncachedata_init_end__; + .ncache : + { + *(NonCacheable) + . = ALIGN(4); + __noncachedata_end__ = .; /* define a global symbol at ncache data end */ + } > m_data + + __DATA_END = __NDATA_ROM + (__noncachedata_init_end__ - __noncachedata_start__); + text_end = ORIGIN(m_text) + LENGTH(m_text); + ASSERT(__DATA_END <= text_end, "region m_text overflowed with text and data") + + /* Uninitialized data section */ + .bss : + { + /* This is used by the startup in order to initialize the .bss section */ + . = ALIGN(4); + __START_BSS = .; + __bss_start__ = .; + *(m_usb_dma_noninit_data) + *(.bss) + *(.bss*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + __END_BSS = .; + } > m_data + + .heap : + { + . = ALIGN(8); + __end__ = .; + PROVIDE(end = .); + PROVIDE(_end = .); + __HeapBase = .; + . += HEAP_SIZE; + __HeapLimit = .; + __heap_limit = .; /* Add for _sbrk */ + __RAM_segment_used_end__ = .; /* Used by ThreadX for first unused memory */ + } > m_data + + .stack : + { + . = ALIGN(8); + . += STACK_SIZE; + } > m_data + + /* Initializes stack on the end of block */ + __StackTop = ORIGIN(m_data) + LENGTH(m_data); + __StackLimit = __StackTop - STACK_SIZE; + PROVIDE(__stack = __StackTop); + PROVIDE(_estack = __StackTop); + + .ARM.attributes 0 : { *(.ARM.attributes) } + + ASSERT(__StackLimit >= __HeapLimit, "region m_data overflowed with stack and heap") +} diff --git a/NXP/MIMXRT1064-EVK/app/startup/startup_mimxrt1064.S b/NXP/MIMXRT1064-EVK/app/startup/startup_mimxrt1064.S new file mode 100644 index 00000000..a2137e4f --- /dev/null +++ b/NXP/MIMXRT1064-EVK/app/startup/startup_mimxrt1064.S @@ -0,0 +1,1146 @@ +/* ------------------------------------------------------------------------- */ +/* @file: startup_MIMXRT1064.s */ +/* @purpose: CMSIS Cortex-M7 Core Device Startup File */ +/* MIMXRT1064 */ +/* @version: 1.3 */ +/* @date: 2021-8-10 */ +/* @build: b231019 */ +/* ------------------------------------------------------------------------- */ +/* */ +/* Copyright 1997-2016 Freescale Semiconductor, Inc. */ +/* Copyright 2016-2023 NXP */ +/* SPDX-License-Identifier: BSD-3-Clause */ +/*****************************************************************************/ +/* Version: GCC for ARM Embedded Processors */ +/*****************************************************************************/ + .syntax unified + .arch armv7-m + + .section .isr_vector, "a" + .align 2 + .globl __isr_vector + .globl __VECTOR_TABLE + .globl __Vectors + .globl _vectors + .globl g_pfnVectors +__isr_vector: +__VECTOR_TABLE: +__Vectors: +_vectors: +g_pfnVectors: + .long __StackTop /* Top of Stack */ + .long Reset_Handler /* Reset Handler */ + .long NMI_Handler /* NMI Handler*/ + .long HardFault_Handler /* Hard Fault Handler*/ + .long MemManage_Handler /* MPU Fault Handler*/ + .long BusFault_Handler /* Bus Fault Handler*/ + .long UsageFault_Handler /* Usage Fault Handler*/ + .long 0 /* Reserved*/ + .long 0 /* Reserved*/ + .long 0 /* Reserved*/ + .long 0 /* Reserved*/ + .long SVC_Handler /* SVCall Handler*/ + .long DebugMon_Handler /* Debug Monitor Handler*/ + .long 0 /* Reserved*/ + .long PendSV_Handler /* PendSV Handler*/ + .long SysTick_Handler /* SysTick Handler*/ + + /* External Interrupts*/ + .long DMA0_DMA16_IRQHandler /* DMA channel 0/16 transfer complete*/ + .long DMA1_DMA17_IRQHandler /* DMA channel 1/17 transfer complete*/ + .long DMA2_DMA18_IRQHandler /* DMA channel 2/18 transfer complete*/ + .long DMA3_DMA19_IRQHandler /* DMA channel 3/19 transfer complete*/ + .long DMA4_DMA20_IRQHandler /* DMA channel 4/20 transfer complete*/ + .long DMA5_DMA21_IRQHandler /* DMA channel 5/21 transfer complete*/ + .long DMA6_DMA22_IRQHandler /* DMA channel 6/22 transfer complete*/ + .long DMA7_DMA23_IRQHandler /* DMA channel 7/23 transfer complete*/ + .long DMA8_DMA24_IRQHandler /* DMA channel 8/24 transfer complete*/ + .long DMA9_DMA25_IRQHandler /* DMA channel 9/25 transfer complete*/ + .long DMA10_DMA26_IRQHandler /* DMA channel 10/26 transfer complete*/ + .long DMA11_DMA27_IRQHandler /* DMA channel 11/27 transfer complete*/ + .long DMA12_DMA28_IRQHandler /* DMA channel 12/28 transfer complete*/ + .long DMA13_DMA29_IRQHandler /* DMA channel 13/29 transfer complete*/ + .long DMA14_DMA30_IRQHandler /* DMA channel 14/30 transfer complete*/ + .long DMA15_DMA31_IRQHandler /* DMA channel 15/31 transfer complete*/ + .long DMA_ERROR_IRQHandler /* DMA error interrupt channels 0-15 / 16-31*/ + .long CTI0_ERROR_IRQHandler /* CTI0_Error*/ + .long CTI1_ERROR_IRQHandler /* CTI1_Error*/ + .long CORE_IRQHandler /* CorePlatform exception IRQ*/ + .long LPUART1_IRQHandler /* LPUART1 TX interrupt and RX interrupt*/ + .long LPUART2_IRQHandler /* LPUART2 TX interrupt and RX interrupt*/ + .long LPUART3_IRQHandler /* LPUART3 TX interrupt and RX interrupt*/ + .long LPUART4_IRQHandler /* LPUART4 TX interrupt and RX interrupt*/ + .long LPUART5_IRQHandler /* LPUART5 TX interrupt and RX interrupt*/ + .long LPUART6_IRQHandler /* LPUART6 TX interrupt and RX interrupt*/ + .long LPUART7_IRQHandler /* LPUART7 TX interrupt and RX interrupt*/ + .long LPUART8_IRQHandler /* LPUART8 TX interrupt and RX interrupt*/ + .long LPI2C1_IRQHandler /* LPI2C1 interrupt*/ + .long LPI2C2_IRQHandler /* LPI2C2 interrupt*/ + .long LPI2C3_IRQHandler /* LPI2C3 interrupt*/ + .long LPI2C4_IRQHandler /* LPI2C4 interrupt*/ + .long LPSPI1_IRQHandler /* LPSPI1 single interrupt vector for all sources*/ + .long LPSPI2_IRQHandler /* LPSPI2 single interrupt vector for all sources*/ + .long LPSPI3_IRQHandler /* LPSPI3 single interrupt vector for all sources*/ + .long LPSPI4_IRQHandler /* LPSPI4 single interrupt vector for all sources*/ + .long CAN1_IRQHandler /* CAN1 interrupt*/ + .long CAN2_IRQHandler /* CAN2 interrupt*/ + .long FLEXRAM_IRQHandler /* FlexRAM address out of range Or access hit IRQ*/ + .long KPP_IRQHandler /* Keypad nterrupt*/ + .long TSC_DIG_IRQHandler /* TSC interrupt*/ + .long GPR_IRQ_IRQHandler /* GPR interrupt*/ + .long LCDIF_IRQHandler /* LCDIF interrupt*/ + .long CSI_IRQHandler /* CSI interrupt*/ + .long PXP_IRQHandler /* PXP interrupt*/ + .long WDOG2_IRQHandler /* WDOG2 interrupt*/ + .long SNVS_HP_WRAPPER_IRQHandler /* SRTC Consolidated Interrupt. Non TZ*/ + .long SNVS_HP_WRAPPER_TZ_IRQHandler /* SRTC Security Interrupt. TZ*/ + .long SNVS_LP_WRAPPER_IRQHandler /* ON-OFF button press shorter than 5 secs (pulse event)*/ + .long CSU_IRQHandler /* CSU interrupt*/ + .long DCP_IRQHandler /* DCP_IRQ interrupt*/ + .long DCP_VMI_IRQHandler /* DCP_VMI_IRQ interrupt*/ + .long Reserved68_IRQHandler /* Reserved interrupt*/ + .long TRNG_IRQHandler /* TRNG interrupt*/ + .long SJC_IRQHandler /* SJC interrupt*/ + .long BEE_IRQHandler /* BEE interrupt*/ + .long SAI1_IRQHandler /* SAI1 interrupt*/ + .long SAI2_IRQHandler /* SAI1 interrupt*/ + .long SAI3_RX_IRQHandler /* SAI3 interrupt*/ + .long SAI3_TX_IRQHandler /* SAI3 interrupt*/ + .long SPDIF_IRQHandler /* SPDIF interrupt*/ + .long PMU_EVENT_IRQHandler /* Brown-out event interrupt*/ + .long Reserved78_IRQHandler /* Reserved interrupt*/ + .long TEMP_LOW_HIGH_IRQHandler /* TempSensor low/high interrupt*/ + .long TEMP_PANIC_IRQHandler /* TempSensor panic interrupt*/ + .long USB_PHY1_IRQHandler /* USBPHY (UTMI0), Interrupt*/ + .long USB_PHY2_IRQHandler /* USBPHY (UTMI1), Interrupt*/ + .long ADC1_IRQHandler /* ADC1 interrupt*/ + .long ADC2_IRQHandler /* ADC2 interrupt*/ + .long DCDC_IRQHandler /* DCDC interrupt*/ + .long Reserved86_IRQHandler /* Reserved interrupt*/ + .long GPIO10_IRQHandler /* GPIO10 interrupt*/ + .long GPIO1_INT0_IRQHandler /* Active HIGH Interrupt from INT0 from GPIO*/ + .long GPIO1_INT1_IRQHandler /* Active HIGH Interrupt from INT1 from GPIO*/ + .long GPIO1_INT2_IRQHandler /* Active HIGH Interrupt from INT2 from GPIO*/ + .long GPIO1_INT3_IRQHandler /* Active HIGH Interrupt from INT3 from GPIO*/ + .long GPIO1_INT4_IRQHandler /* Active HIGH Interrupt from INT4 from GPIO*/ + .long GPIO1_INT5_IRQHandler /* Active HIGH Interrupt from INT5 from GPIO*/ + .long GPIO1_INT6_IRQHandler /* Active HIGH Interrupt from INT6 from GPIO*/ + .long GPIO1_INT7_IRQHandler /* Active HIGH Interrupt from INT7 from GPIO*/ + .long GPIO1_Combined_0_15_IRQHandler /* Combined interrupt indication for GPIO1 signal 0 throughout 15*/ + .long GPIO1_Combined_16_31_IRQHandler /* Combined interrupt indication for GPIO1 signal 16 throughout 31*/ + .long GPIO2_Combined_0_15_IRQHandler /* Combined interrupt indication for GPIO2 signal 0 throughout 15*/ + .long GPIO2_Combined_16_31_IRQHandler /* Combined interrupt indication for GPIO2 signal 16 throughout 31*/ + .long GPIO3_Combined_0_15_IRQHandler /* Combined interrupt indication for GPIO3 signal 0 throughout 15*/ + .long GPIO3_Combined_16_31_IRQHandler /* Combined interrupt indication for GPIO3 signal 16 throughout 31*/ + .long GPIO4_Combined_0_15_IRQHandler /* Combined interrupt indication for GPIO4 signal 0 throughout 15*/ + .long GPIO4_Combined_16_31_IRQHandler /* Combined interrupt indication for GPIO4 signal 16 throughout 31*/ + .long GPIO5_Combined_0_15_IRQHandler /* Combined interrupt indication for GPIO5 signal 0 throughout 15*/ + .long GPIO5_Combined_16_31_IRQHandler /* Combined interrupt indication for GPIO5 signal 16 throughout 31*/ + .long FLEXIO1_IRQHandler /* FLEXIO1 interrupt*/ + .long FLEXIO2_IRQHandler /* FLEXIO2 interrupt*/ + .long WDOG1_IRQHandler /* WDOG1 interrupt*/ + .long RTWDOG_IRQHandler /* RTWDOG interrupt*/ + .long EWM_IRQHandler /* EWM interrupt*/ + .long CCM_1_IRQHandler /* CCM IRQ1 interrupt*/ + .long CCM_2_IRQHandler /* CCM IRQ2 interrupt*/ + .long GPC_IRQHandler /* GPC interrupt*/ + .long SRC_IRQHandler /* SRC interrupt*/ + .long Reserved115_IRQHandler /* Reserved interrupt*/ + .long GPT1_IRQHandler /* GPT1 interrupt*/ + .long GPT2_IRQHandler /* GPT2 interrupt*/ + .long PWM1_0_IRQHandler /* PWM1 capture 0, compare 0, or reload 0 interrupt*/ + .long PWM1_1_IRQHandler /* PWM1 capture 1, compare 1, or reload 0 interrupt*/ + .long PWM1_2_IRQHandler /* PWM1 capture 2, compare 2, or reload 0 interrupt*/ + .long PWM1_3_IRQHandler /* PWM1 capture 3, compare 3, or reload 0 interrupt*/ + .long PWM1_FAULT_IRQHandler /* PWM1 fault or reload error interrupt*/ + .long FLEXSPI2_IRQHandler /* FlexSPI2 interrupt*/ + .long FLEXSPI_IRQHandler /* FlexSPI0 interrupt*/ + .long SEMC_IRQHandler /* SEMC interrupt*/ + .long USDHC1_IRQHandler /* USDHC1 interrupt*/ + .long USDHC2_IRQHandler /* USDHC2 interrupt*/ + .long USB_OTG2_IRQHandler /* USBO2 USB OTG2*/ + .long USB_OTG1_IRQHandler /* USBO2 USB OTG1*/ + .long ENET_IRQHandler /* ENET interrupt*/ + .long ENET_1588_Timer_IRQHandler /* ENET_1588_Timer interrupt*/ + .long XBAR1_IRQ_0_1_IRQHandler /* XBARA1 output signal 0, 1 interrupt*/ + .long XBAR1_IRQ_2_3_IRQHandler /* XBARA1 output signal 2, 3 interrupt*/ + .long ADC_ETC_IRQ0_IRQHandler /* ADCETC IRQ0 interrupt*/ + .long ADC_ETC_IRQ1_IRQHandler /* ADCETC IRQ1 interrupt*/ + .long ADC_ETC_IRQ2_IRQHandler /* ADCETC IRQ2 interrupt*/ + .long ADC_ETC_ERROR_IRQ_IRQHandler /* ADCETC Error IRQ interrupt*/ + .long PIT_IRQHandler /* PIT interrupt*/ + .long ACMP1_IRQHandler /* ACMP interrupt*/ + .long ACMP2_IRQHandler /* ACMP interrupt*/ + .long ACMP3_IRQHandler /* ACMP interrupt*/ + .long ACMP4_IRQHandler /* ACMP interrupt*/ + .long Reserved143_IRQHandler /* Reserved interrupt*/ + .long Reserved144_IRQHandler /* Reserved interrupt*/ + .long ENC1_IRQHandler /* ENC1 interrupt*/ + .long ENC2_IRQHandler /* ENC2 interrupt*/ + .long ENC3_IRQHandler /* ENC3 interrupt*/ + .long ENC4_IRQHandler /* ENC4 interrupt*/ + .long TMR1_IRQHandler /* TMR1 interrupt*/ + .long TMR2_IRQHandler /* TMR2 interrupt*/ + .long TMR3_IRQHandler /* TMR3 interrupt*/ + .long TMR4_IRQHandler /* TMR4 interrupt*/ + .long PWM2_0_IRQHandler /* PWM2 capture 0, compare 0, or reload 0 interrupt*/ + .long PWM2_1_IRQHandler /* PWM2 capture 1, compare 1, or reload 0 interrupt*/ + .long PWM2_2_IRQHandler /* PWM2 capture 2, compare 2, or reload 0 interrupt*/ + .long PWM2_3_IRQHandler /* PWM2 capture 3, compare 3, or reload 0 interrupt*/ + .long PWM2_FAULT_IRQHandler /* PWM2 fault or reload error interrupt*/ + .long PWM3_0_IRQHandler /* PWM3 capture 0, compare 0, or reload 0 interrupt*/ + .long PWM3_1_IRQHandler /* PWM3 capture 1, compare 1, or reload 0 interrupt*/ + .long PWM3_2_IRQHandler /* PWM3 capture 2, compare 2, or reload 0 interrupt*/ + .long PWM3_3_IRQHandler /* PWM3 capture 3, compare 3, or reload 0 interrupt*/ + .long PWM3_FAULT_IRQHandler /* PWM3 fault or reload error interrupt*/ + .long PWM4_0_IRQHandler /* PWM4 capture 0, compare 0, or reload 0 interrupt*/ + .long PWM4_1_IRQHandler /* PWM4 capture 1, compare 1, or reload 0 interrupt*/ + .long PWM4_2_IRQHandler /* PWM4 capture 2, compare 2, or reload 0 interrupt*/ + .long PWM4_3_IRQHandler /* PWM4 capture 3, compare 3, or reload 0 interrupt*/ + .long PWM4_FAULT_IRQHandler /* PWM4 fault or reload error interrupt*/ + .long ENET2_IRQHandler /* ENET2 interrupt*/ + .long ENET2_1588_Timer_IRQHandler /* ENET2_1588_Timer interrupt*/ + .long CAN3_IRQHandler /* CAN3 interrupt*/ + .long Reserved171_IRQHandler /* Reserved interrupt*/ + .long FLEXIO3_IRQHandler /* FLEXIO3 interrupt*/ + .long GPIO6_7_8_9_IRQHandler /* GPIO6, GPIO7, GPIO8, GPIO9 interrupt*/ + .long DefaultISR /* 174*/ + .long DefaultISR /* 175*/ + .long DefaultISR /* 176*/ + .long DefaultISR /* 177*/ + .long DefaultISR /* 178*/ + .long DefaultISR /* 179*/ + .long DefaultISR /* 180*/ + .long DefaultISR /* 181*/ + .long DefaultISR /* 182*/ + .long DefaultISR /* 183*/ + .long DefaultISR /* 184*/ + .long DefaultISR /* 185*/ + .long DefaultISR /* 186*/ + .long DefaultISR /* 187*/ + .long DefaultISR /* 188*/ + .long DefaultISR /* 189*/ + .long DefaultISR /* 190*/ + .long DefaultISR /* 191*/ + .long DefaultISR /* 192*/ + .long DefaultISR /* 193*/ + .long DefaultISR /* 194*/ + .long DefaultISR /* 195*/ + .long DefaultISR /* 196*/ + .long DefaultISR /* 197*/ + .long DefaultISR /* 198*/ + .long DefaultISR /* 199*/ + .long DefaultISR /* 200*/ + .long DefaultISR /* 201*/ + .long DefaultISR /* 202*/ + .long DefaultISR /* 203*/ + .long DefaultISR /* 204*/ + .long DefaultISR /* 205*/ + .long DefaultISR /* 206*/ + .long DefaultISR /* 207*/ + .long DefaultISR /* 208*/ + .long DefaultISR /* 209*/ + .long DefaultISR /* 210*/ + .long DefaultISR /* 211*/ + .long DefaultISR /* 212*/ + .long DefaultISR /* 213*/ + .long DefaultISR /* 214*/ + .long DefaultISR /* 215*/ + .long DefaultISR /* 216*/ + .long DefaultISR /* 217*/ + .long DefaultISR /* 218*/ + .long DefaultISR /* 219*/ + .long DefaultISR /* 220*/ + .long DefaultISR /* 221*/ + .long DefaultISR /* 222*/ + .long DefaultISR /* 223*/ + .long DefaultISR /* 224*/ + .long DefaultISR /* 225*/ + .long DefaultISR /* 226*/ + .long DefaultISR /* 227*/ + .long DefaultISR /* 228*/ + .long DefaultISR /* 229*/ + .long DefaultISR /* 230*/ + .long DefaultISR /* 231*/ + .long DefaultISR /* 232*/ + .long DefaultISR /* 233*/ + .long DefaultISR /* 234*/ + .long DefaultISR /* 235*/ + .long DefaultISR /* 236*/ + .long DefaultISR /* 237*/ + .long DefaultISR /* 238*/ + .long DefaultISR /* 239*/ + .long DefaultISR /* 240*/ + .long DefaultISR /* 241*/ + .long DefaultISR /* 242*/ + .long DefaultISR /* 243*/ + .long DefaultISR /* 244*/ + .long DefaultISR /* 245*/ + .long DefaultISR /* 246*/ + .long DefaultISR /* 247*/ + .long DefaultISR /* 248*/ + .long DefaultISR /* 249*/ + .long DefaultISR /* 250*/ + .long DefaultISR /* 251*/ + .long DefaultISR /* 252*/ + .long DefaultISR /* 253*/ + .long DefaultISR /* 254*/ + .long 0xFFFFFFFF /* Reserved for user TRIM value*/ + + .size __isr_vector, . - __isr_vector + + .text + .thumb + +#if defined (__cplusplus) +#ifdef __REDLIB__ +#error Redlib does not support C++ +#endif +#endif +/* Reset Handler */ + + .thumb_func + .align 2 + .globl Reset_Handler + .weak Reset_Handler + .type Reset_Handler, %function +Reset_Handler: + cpsid i /* Mask interrupts */ + .equ VTOR, 0xE000ED08 + ldr r0, =VTOR + ldr r1, =__isr_vector + str r1, [r0] + ldr r2, [r1] + msr msp, r2 +#ifndef __NO_SYSTEM_INIT + ldr r0,=SystemInit + blx r0 +#endif +/* Loop to copy data from read only memory to RAM. The ranges + * of copy from/to are specified by following symbols evaluated in + * linker script. + * __etext: End of code section, i.e., begin of data sections to copy from. + * __data_start__/__data_end__: RAM address range that data should be + * __noncachedata_start__/__noncachedata_end__ : none cachable region + * __ram_function_start__/__ram_function_end__ : ramfunction region + * copied to. Both must be aligned to 4 bytes boundary. */ + + ldr r1, =__etext + ldr r2, =__data_start__ + ldr r3, =__data_end__ + +#ifdef __PERFORMANCE_IMPLEMENTATION +/* Here are two copies of loop implementations. First one favors performance + * and the second one favors code size. Default uses the second one. + * Define macro "__PERFORMANCE_IMPLEMENTATION" in project to use the first one */ + subs r3, r2 + ble .LC1 +.LC0: + subs r3, #4 + ldr r0, [r1, r3] + str r0, [r2, r3] + bgt .LC0 +.LC1: +#else /* code size implemenation */ +.LC0: + cmp r2, r3 + ittt lt + ldrlt r0, [r1], #4 + strlt r0, [r2], #4 + blt .LC0 +#endif +#ifdef __STARTUP_INITIALIZE_RAMFUNCTION + ldr r2, =__ram_function_start__ + ldr r3, =__ram_function_end__ +#ifdef __PERFORMANCE_IMPLEMENTATION +/* Here are two copies of loop implementations. First one favors performance + * and the second one favors code size. Default uses the second one. + * Define macro "__PERFORMANCE_IMPLEMENTATION" in project to use the first one */ + subs r3, r2 + ble .LC_ramfunc_copy_end +.LC_ramfunc_copy_start: + subs r3, #4 + ldr r0, [r1, r3] + str r0, [r2, r3] + bgt .LC_ramfunc_copy_start +.LC_ramfunc_copy_end: +#else /* code size implemenation */ +.LC_ramfunc_copy_start: + cmp r2, r3 + ittt lt + ldrlt r0, [r1], #4 + strlt r0, [r2], #4 + blt .LC_ramfunc_copy_start +#endif +#endif /* __STARTUP_INITIALIZE_RAMFUNCTION */ +#ifdef __STARTUP_INITIALIZE_NONCACHEDATA + ldr r2, =__noncachedata_start__ + ldr r3, =__noncachedata_init_end__ +#ifdef __PERFORMANCE_IMPLEMENTATION +/* Here are two copies of loop implementations. First one favors performance + * and the second one favors code size. Default uses the second one. + * Define macro "__PERFORMANCE_IMPLEMENTATION" in project to use the first one */ + subs r3, r2 + ble .LC3 +.LC2: + subs r3, #4 + ldr r0, [r1, r3] + str r0, [r2, r3] + bgt .LC2 +.LC3: +#else /* code size implemenation */ +.LC2: + cmp r2, r3 + ittt lt + ldrlt r0, [r1], #4 + strlt r0, [r2], #4 + blt .LC2 +#endif +/* zero inited ncache section initialization */ + ldr r3, =__noncachedata_end__ + movs r0,0 +.LC4: + cmp r2,r3 + itt lt + strlt r0,[r2],#4 + blt .LC4 +#endif /* __STARTUP_INITIALIZE_NONCACHEDATA */ + +#ifndef __STARTUP_CLEAR_BSS +#define __STARTUP_CLEAR_BSS +#endif + +#ifdef __STARTUP_CLEAR_BSS +/* This part of work usually is done in C library startup code. Otherwise, + * define this macro to enable it in this startup. + * + * Loop to zero out BSS section, which uses following symbols + * in linker script: + * __bss_start__: start of BSS section. Must align to 4 + * __bss_end__: end of BSS section. Must align to 4 + */ + ldr r1, =__bss_start__ + ldr r2, =__bss_end__ + + movs r0, 0 +.LC5: + cmp r1, r2 + itt lt + strlt r0, [r1], #4 + blt .LC5 +#endif /* __STARTUP_CLEAR_BSS */ + + cpsie i /* Unmask interrupts */ +#ifndef __START +#ifdef __REDLIB__ +#define __START __main +#else +#define __START _start +#endif +#endif +#ifndef __ATOLLIC__ + ldr r0,=__START + blx r0 +#else + ldr r0,=__libc_init_array + blx r0 + ldr r0,=main + bx r0 +#endif + .pool + .size Reset_Handler, . - Reset_Handler + + .align 1 + .thumb_func + .weak DefaultISR + .type DefaultISR, %function +DefaultISR: + b DefaultISR + .size DefaultISR, . - DefaultISR + + .align 1 + .thumb_func + .weak NMI_Handler + .type NMI_Handler, %function +NMI_Handler: + ldr r0,=NMI_Handler + bx r0 + .size NMI_Handler, . - NMI_Handler + + .align 1 + .thumb_func + .weak HardFault_Handler + .type HardFault_Handler, %function +HardFault_Handler: + ldr r0,=HardFault_Handler + bx r0 + .size HardFault_Handler, . - HardFault_Handler + + .align 1 + .thumb_func + .weak SVC_Handler + .type SVC_Handler, %function +SVC_Handler: + ldr r0,=SVC_Handler + bx r0 + .size SVC_Handler, . - SVC_Handler + + .align 1 + .thumb_func + .weak PendSV_Handler + .type PendSV_Handler, %function +PendSV_Handler: + ldr r0,=PendSV_Handler + bx r0 + .size PendSV_Handler, . - PendSV_Handler + + .align 1 + .thumb_func + .weak SysTick_Handler + .type SysTick_Handler, %function +SysTick_Handler: + ldr r0,=SysTick_Handler + bx r0 + .size SysTick_Handler, . - SysTick_Handler + + .align 1 + .thumb_func + .weak DMA0_DMA16_IRQHandler + .type DMA0_DMA16_IRQHandler, %function +DMA0_DMA16_IRQHandler: + ldr r0,=DMA0_DMA16_DriverIRQHandler + bx r0 + .size DMA0_DMA16_IRQHandler, . - DMA0_DMA16_IRQHandler + + .align 1 + .thumb_func + .weak DMA1_DMA17_IRQHandler + .type DMA1_DMA17_IRQHandler, %function +DMA1_DMA17_IRQHandler: + ldr r0,=DMA1_DMA17_DriverIRQHandler + bx r0 + .size DMA1_DMA17_IRQHandler, . - DMA1_DMA17_IRQHandler + + .align 1 + .thumb_func + .weak DMA2_DMA18_IRQHandler + .type DMA2_DMA18_IRQHandler, %function +DMA2_DMA18_IRQHandler: + ldr r0,=DMA2_DMA18_DriverIRQHandler + bx r0 + .size DMA2_DMA18_IRQHandler, . - DMA2_DMA18_IRQHandler + + .align 1 + .thumb_func + .weak DMA3_DMA19_IRQHandler + .type DMA3_DMA19_IRQHandler, %function +DMA3_DMA19_IRQHandler: + ldr r0,=DMA3_DMA19_DriverIRQHandler + bx r0 + .size DMA3_DMA19_IRQHandler, . - DMA3_DMA19_IRQHandler + + .align 1 + .thumb_func + .weak DMA4_DMA20_IRQHandler + .type DMA4_DMA20_IRQHandler, %function +DMA4_DMA20_IRQHandler: + ldr r0,=DMA4_DMA20_DriverIRQHandler + bx r0 + .size DMA4_DMA20_IRQHandler, . - DMA4_DMA20_IRQHandler + + .align 1 + .thumb_func + .weak DMA5_DMA21_IRQHandler + .type DMA5_DMA21_IRQHandler, %function +DMA5_DMA21_IRQHandler: + ldr r0,=DMA5_DMA21_DriverIRQHandler + bx r0 + .size DMA5_DMA21_IRQHandler, . - DMA5_DMA21_IRQHandler + + .align 1 + .thumb_func + .weak DMA6_DMA22_IRQHandler + .type DMA6_DMA22_IRQHandler, %function +DMA6_DMA22_IRQHandler: + ldr r0,=DMA6_DMA22_DriverIRQHandler + bx r0 + .size DMA6_DMA22_IRQHandler, . - DMA6_DMA22_IRQHandler + + .align 1 + .thumb_func + .weak DMA7_DMA23_IRQHandler + .type DMA7_DMA23_IRQHandler, %function +DMA7_DMA23_IRQHandler: + ldr r0,=DMA7_DMA23_DriverIRQHandler + bx r0 + .size DMA7_DMA23_IRQHandler, . - DMA7_DMA23_IRQHandler + + .align 1 + .thumb_func + .weak DMA8_DMA24_IRQHandler + .type DMA8_DMA24_IRQHandler, %function +DMA8_DMA24_IRQHandler: + ldr r0,=DMA8_DMA24_DriverIRQHandler + bx r0 + .size DMA8_DMA24_IRQHandler, . - DMA8_DMA24_IRQHandler + + .align 1 + .thumb_func + .weak DMA9_DMA25_IRQHandler + .type DMA9_DMA25_IRQHandler, %function +DMA9_DMA25_IRQHandler: + ldr r0,=DMA9_DMA25_DriverIRQHandler + bx r0 + .size DMA9_DMA25_IRQHandler, . - DMA9_DMA25_IRQHandler + + .align 1 + .thumb_func + .weak DMA10_DMA26_IRQHandler + .type DMA10_DMA26_IRQHandler, %function +DMA10_DMA26_IRQHandler: + ldr r0,=DMA10_DMA26_DriverIRQHandler + bx r0 + .size DMA10_DMA26_IRQHandler, . - DMA10_DMA26_IRQHandler + + .align 1 + .thumb_func + .weak DMA11_DMA27_IRQHandler + .type DMA11_DMA27_IRQHandler, %function +DMA11_DMA27_IRQHandler: + ldr r0,=DMA11_DMA27_DriverIRQHandler + bx r0 + .size DMA11_DMA27_IRQHandler, . - DMA11_DMA27_IRQHandler + + .align 1 + .thumb_func + .weak DMA12_DMA28_IRQHandler + .type DMA12_DMA28_IRQHandler, %function +DMA12_DMA28_IRQHandler: + ldr r0,=DMA12_DMA28_DriverIRQHandler + bx r0 + .size DMA12_DMA28_IRQHandler, . - DMA12_DMA28_IRQHandler + + .align 1 + .thumb_func + .weak DMA13_DMA29_IRQHandler + .type DMA13_DMA29_IRQHandler, %function +DMA13_DMA29_IRQHandler: + ldr r0,=DMA13_DMA29_DriverIRQHandler + bx r0 + .size DMA13_DMA29_IRQHandler, . - DMA13_DMA29_IRQHandler + + .align 1 + .thumb_func + .weak DMA14_DMA30_IRQHandler + .type DMA14_DMA30_IRQHandler, %function +DMA14_DMA30_IRQHandler: + ldr r0,=DMA14_DMA30_DriverIRQHandler + bx r0 + .size DMA14_DMA30_IRQHandler, . - DMA14_DMA30_IRQHandler + + .align 1 + .thumb_func + .weak DMA15_DMA31_IRQHandler + .type DMA15_DMA31_IRQHandler, %function +DMA15_DMA31_IRQHandler: + ldr r0,=DMA15_DMA31_DriverIRQHandler + bx r0 + .size DMA15_DMA31_IRQHandler, . - DMA15_DMA31_IRQHandler + + .align 1 + .thumb_func + .weak DMA_ERROR_IRQHandler + .type DMA_ERROR_IRQHandler, %function +DMA_ERROR_IRQHandler: + ldr r0,=DMA_ERROR_DriverIRQHandler + bx r0 + .size DMA_ERROR_IRQHandler, . - DMA_ERROR_IRQHandler + + .align 1 + .thumb_func + .weak LPUART1_IRQHandler + .type LPUART1_IRQHandler, %function +LPUART1_IRQHandler: + ldr r0,=LPUART1_DriverIRQHandler + bx r0 + .size LPUART1_IRQHandler, . - LPUART1_IRQHandler + + .align 1 + .thumb_func + .weak LPUART2_IRQHandler + .type LPUART2_IRQHandler, %function +LPUART2_IRQHandler: + ldr r0,=LPUART2_DriverIRQHandler + bx r0 + .size LPUART2_IRQHandler, . - LPUART2_IRQHandler + + .align 1 + .thumb_func + .weak LPUART3_IRQHandler + .type LPUART3_IRQHandler, %function +LPUART3_IRQHandler: + ldr r0,=LPUART3_DriverIRQHandler + bx r0 + .size LPUART3_IRQHandler, . - LPUART3_IRQHandler + + .align 1 + .thumb_func + .weak LPUART4_IRQHandler + .type LPUART4_IRQHandler, %function +LPUART4_IRQHandler: + ldr r0,=LPUART4_DriverIRQHandler + bx r0 + .size LPUART4_IRQHandler, . - LPUART4_IRQHandler + + .align 1 + .thumb_func + .weak LPUART5_IRQHandler + .type LPUART5_IRQHandler, %function +LPUART5_IRQHandler: + ldr r0,=LPUART5_DriverIRQHandler + bx r0 + .size LPUART5_IRQHandler, . - LPUART5_IRQHandler + + .align 1 + .thumb_func + .weak LPUART6_IRQHandler + .type LPUART6_IRQHandler, %function +LPUART6_IRQHandler: + ldr r0,=LPUART6_DriverIRQHandler + bx r0 + .size LPUART6_IRQHandler, . - LPUART6_IRQHandler + + .align 1 + .thumb_func + .weak LPUART7_IRQHandler + .type LPUART7_IRQHandler, %function +LPUART7_IRQHandler: + ldr r0,=LPUART7_DriverIRQHandler + bx r0 + .size LPUART7_IRQHandler, . - LPUART7_IRQHandler + + .align 1 + .thumb_func + .weak LPUART8_IRQHandler + .type LPUART8_IRQHandler, %function +LPUART8_IRQHandler: + ldr r0,=LPUART8_DriverIRQHandler + bx r0 + .size LPUART8_IRQHandler, . - LPUART8_IRQHandler + + .align 1 + .thumb_func + .weak LPI2C1_IRQHandler + .type LPI2C1_IRQHandler, %function +LPI2C1_IRQHandler: + ldr r0,=LPI2C1_DriverIRQHandler + bx r0 + .size LPI2C1_IRQHandler, . - LPI2C1_IRQHandler + + .align 1 + .thumb_func + .weak LPI2C2_IRQHandler + .type LPI2C2_IRQHandler, %function +LPI2C2_IRQHandler: + ldr r0,=LPI2C2_DriverIRQHandler + bx r0 + .size LPI2C2_IRQHandler, . - LPI2C2_IRQHandler + + .align 1 + .thumb_func + .weak LPI2C3_IRQHandler + .type LPI2C3_IRQHandler, %function +LPI2C3_IRQHandler: + ldr r0,=LPI2C3_DriverIRQHandler + bx r0 + .size LPI2C3_IRQHandler, . - LPI2C3_IRQHandler + + .align 1 + .thumb_func + .weak LPI2C4_IRQHandler + .type LPI2C4_IRQHandler, %function +LPI2C4_IRQHandler: + ldr r0,=LPI2C4_DriverIRQHandler + bx r0 + .size LPI2C4_IRQHandler, . - LPI2C4_IRQHandler + + .align 1 + .thumb_func + .weak LPSPI1_IRQHandler + .type LPSPI1_IRQHandler, %function +LPSPI1_IRQHandler: + ldr r0,=LPSPI1_DriverIRQHandler + bx r0 + .size LPSPI1_IRQHandler, . - LPSPI1_IRQHandler + + .align 1 + .thumb_func + .weak LPSPI2_IRQHandler + .type LPSPI2_IRQHandler, %function +LPSPI2_IRQHandler: + ldr r0,=LPSPI2_DriverIRQHandler + bx r0 + .size LPSPI2_IRQHandler, . - LPSPI2_IRQHandler + + .align 1 + .thumb_func + .weak LPSPI3_IRQHandler + .type LPSPI3_IRQHandler, %function +LPSPI3_IRQHandler: + ldr r0,=LPSPI3_DriverIRQHandler + bx r0 + .size LPSPI3_IRQHandler, . - LPSPI3_IRQHandler + + .align 1 + .thumb_func + .weak LPSPI4_IRQHandler + .type LPSPI4_IRQHandler, %function +LPSPI4_IRQHandler: + ldr r0,=LPSPI4_DriverIRQHandler + bx r0 + .size LPSPI4_IRQHandler, . - LPSPI4_IRQHandler + + .align 1 + .thumb_func + .weak CAN1_IRQHandler + .type CAN1_IRQHandler, %function +CAN1_IRQHandler: + ldr r0,=CAN1_DriverIRQHandler + bx r0 + .size CAN1_IRQHandler, . - CAN1_IRQHandler + + .align 1 + .thumb_func + .weak CAN2_IRQHandler + .type CAN2_IRQHandler, %function +CAN2_IRQHandler: + ldr r0,=CAN2_DriverIRQHandler + bx r0 + .size CAN2_IRQHandler, . - CAN2_IRQHandler + + .align 1 + .thumb_func + .weak SAI1_IRQHandler + .type SAI1_IRQHandler, %function +SAI1_IRQHandler: + ldr r0,=SAI1_DriverIRQHandler + bx r0 + .size SAI1_IRQHandler, . - SAI1_IRQHandler + + .align 1 + .thumb_func + .weak SAI2_IRQHandler + .type SAI2_IRQHandler, %function +SAI2_IRQHandler: + ldr r0,=SAI2_DriverIRQHandler + bx r0 + .size SAI2_IRQHandler, . - SAI2_IRQHandler + + .align 1 + .thumb_func + .weak SAI3_RX_IRQHandler + .type SAI3_RX_IRQHandler, %function +SAI3_RX_IRQHandler: + ldr r0,=SAI3_RX_DriverIRQHandler + bx r0 + .size SAI3_RX_IRQHandler, . - SAI3_RX_IRQHandler + + .align 1 + .thumb_func + .weak SAI3_TX_IRQHandler + .type SAI3_TX_IRQHandler, %function +SAI3_TX_IRQHandler: + ldr r0,=SAI3_TX_DriverIRQHandler + bx r0 + .size SAI3_TX_IRQHandler, . - SAI3_TX_IRQHandler + + .align 1 + .thumb_func + .weak SPDIF_IRQHandler + .type SPDIF_IRQHandler, %function +SPDIF_IRQHandler: + ldr r0,=SPDIF_DriverIRQHandler + bx r0 + .size SPDIF_IRQHandler, . - SPDIF_IRQHandler + + .align 1 + .thumb_func + .weak FLEXIO1_IRQHandler + .type FLEXIO1_IRQHandler, %function +FLEXIO1_IRQHandler: + ldr r0,=FLEXIO1_DriverIRQHandler + bx r0 + .size FLEXIO1_IRQHandler, . - FLEXIO1_IRQHandler + + .align 1 + .thumb_func + .weak FLEXIO2_IRQHandler + .type FLEXIO2_IRQHandler, %function +FLEXIO2_IRQHandler: + ldr r0,=FLEXIO2_DriverIRQHandler + bx r0 + .size FLEXIO2_IRQHandler, . - FLEXIO2_IRQHandler + + .align 1 + .thumb_func + .weak FLEXSPI2_IRQHandler + .type FLEXSPI2_IRQHandler, %function +FLEXSPI2_IRQHandler: + ldr r0,=FLEXSPI2_DriverIRQHandler + bx r0 + .size FLEXSPI2_IRQHandler, . - FLEXSPI2_IRQHandler + + .align 1 + .thumb_func + .weak FLEXSPI_IRQHandler + .type FLEXSPI_IRQHandler, %function +FLEXSPI_IRQHandler: + ldr r0,=FLEXSPI_DriverIRQHandler + bx r0 + .size FLEXSPI_IRQHandler, . - FLEXSPI_IRQHandler + + .align 1 + .thumb_func + .weak USDHC1_IRQHandler + .type USDHC1_IRQHandler, %function +USDHC1_IRQHandler: + ldr r0,=USDHC1_DriverIRQHandler + bx r0 + .size USDHC1_IRQHandler, . - USDHC1_IRQHandler + + .align 1 + .thumb_func + .weak USDHC2_IRQHandler + .type USDHC2_IRQHandler, %function +USDHC2_IRQHandler: + ldr r0,=USDHC2_DriverIRQHandler + bx r0 + .size USDHC2_IRQHandler, . - USDHC2_IRQHandler + + .align 1 + .thumb_func + .weak ENET_IRQHandler + .type ENET_IRQHandler, %function +ENET_IRQHandler: + ldr r0,=ENET_DriverIRQHandler + bx r0 + .size ENET_IRQHandler, . - ENET_IRQHandler + + .align 1 + .thumb_func + .weak ENET_1588_Timer_IRQHandler + .type ENET_1588_Timer_IRQHandler, %function +ENET_1588_Timer_IRQHandler: + ldr r0,=ENET_1588_Timer_DriverIRQHandler + bx r0 + .size ENET_1588_Timer_IRQHandler, . - ENET_1588_Timer_IRQHandler + + .align 1 + .thumb_func + .weak ENET2_IRQHandler + .type ENET2_IRQHandler, %function +ENET2_IRQHandler: + ldr r0,=ENET2_DriverIRQHandler + bx r0 + .size ENET2_IRQHandler, . - ENET2_IRQHandler + + .align 1 + .thumb_func + .weak ENET2_1588_Timer_IRQHandler + .type ENET2_1588_Timer_IRQHandler, %function +ENET2_1588_Timer_IRQHandler: + ldr r0,=ENET2_1588_Timer_DriverIRQHandler + bx r0 + .size ENET2_1588_Timer_IRQHandler, . - ENET2_1588_Timer_IRQHandler + + .align 1 + .thumb_func + .weak CAN3_IRQHandler + .type CAN3_IRQHandler, %function +CAN3_IRQHandler: + ldr r0,=CAN3_DriverIRQHandler + bx r0 + .size CAN3_IRQHandler, . - CAN3_IRQHandler + + .align 1 + .thumb_func + .weak FLEXIO3_IRQHandler + .type FLEXIO3_IRQHandler, %function +FLEXIO3_IRQHandler: + ldr r0,=FLEXIO3_DriverIRQHandler + bx r0 + .size FLEXIO3_IRQHandler, . - FLEXIO3_IRQHandler + + +/* Macro to define default handlers. Default handler + * will be weak symbol and just dead loops. They can be + * overwritten by other handlers */ + .macro def_irq_handler handler_name + .weak \handler_name + .set \handler_name, DefaultISR + .endm +/* Exception Handlers */ + def_irq_handler MemManage_Handler + def_irq_handler BusFault_Handler + def_irq_handler UsageFault_Handler + def_irq_handler DebugMon_Handler + def_irq_handler DMA0_DMA16_DriverIRQHandler + def_irq_handler DMA1_DMA17_DriverIRQHandler + def_irq_handler DMA2_DMA18_DriverIRQHandler + def_irq_handler DMA3_DMA19_DriverIRQHandler + def_irq_handler DMA4_DMA20_DriverIRQHandler + def_irq_handler DMA5_DMA21_DriverIRQHandler + def_irq_handler DMA6_DMA22_DriverIRQHandler + def_irq_handler DMA7_DMA23_DriverIRQHandler + def_irq_handler DMA8_DMA24_DriverIRQHandler + def_irq_handler DMA9_DMA25_DriverIRQHandler + def_irq_handler DMA10_DMA26_DriverIRQHandler + def_irq_handler DMA11_DMA27_DriverIRQHandler + def_irq_handler DMA12_DMA28_DriverIRQHandler + def_irq_handler DMA13_DMA29_DriverIRQHandler + def_irq_handler DMA14_DMA30_DriverIRQHandler + def_irq_handler DMA15_DMA31_DriverIRQHandler + def_irq_handler DMA_ERROR_DriverIRQHandler + def_irq_handler CTI0_ERROR_IRQHandler + def_irq_handler CTI1_ERROR_IRQHandler + def_irq_handler CORE_IRQHandler + def_irq_handler LPUART1_DriverIRQHandler + def_irq_handler LPUART2_DriverIRQHandler + def_irq_handler LPUART3_DriverIRQHandler + def_irq_handler LPUART4_DriverIRQHandler + def_irq_handler LPUART5_DriverIRQHandler + def_irq_handler LPUART6_DriverIRQHandler + def_irq_handler LPUART7_DriverIRQHandler + def_irq_handler LPUART8_DriverIRQHandler + def_irq_handler LPI2C1_DriverIRQHandler + def_irq_handler LPI2C2_DriverIRQHandler + def_irq_handler LPI2C3_DriverIRQHandler + def_irq_handler LPI2C4_DriverIRQHandler + def_irq_handler LPSPI1_DriverIRQHandler + def_irq_handler LPSPI2_DriverIRQHandler + def_irq_handler LPSPI3_DriverIRQHandler + def_irq_handler LPSPI4_DriverIRQHandler + def_irq_handler CAN1_DriverIRQHandler + def_irq_handler CAN2_DriverIRQHandler + def_irq_handler FLEXRAM_IRQHandler + def_irq_handler KPP_IRQHandler + def_irq_handler TSC_DIG_IRQHandler + def_irq_handler GPR_IRQ_IRQHandler + def_irq_handler LCDIF_IRQHandler + def_irq_handler CSI_IRQHandler + def_irq_handler PXP_IRQHandler + def_irq_handler WDOG2_IRQHandler + def_irq_handler SNVS_HP_WRAPPER_IRQHandler + def_irq_handler SNVS_HP_WRAPPER_TZ_IRQHandler + def_irq_handler SNVS_LP_WRAPPER_IRQHandler + def_irq_handler CSU_IRQHandler + def_irq_handler DCP_IRQHandler + def_irq_handler DCP_VMI_IRQHandler + def_irq_handler Reserved68_IRQHandler + def_irq_handler TRNG_IRQHandler + def_irq_handler SJC_IRQHandler + def_irq_handler BEE_IRQHandler + def_irq_handler SAI1_DriverIRQHandler + def_irq_handler SAI2_DriverIRQHandler + def_irq_handler SAI3_RX_DriverIRQHandler + def_irq_handler SAI3_TX_DriverIRQHandler + def_irq_handler SPDIF_DriverIRQHandler + def_irq_handler PMU_EVENT_IRQHandler + def_irq_handler Reserved78_IRQHandler + def_irq_handler TEMP_LOW_HIGH_IRQHandler + def_irq_handler TEMP_PANIC_IRQHandler + def_irq_handler USB_PHY1_IRQHandler + def_irq_handler USB_PHY2_IRQHandler + def_irq_handler ADC1_IRQHandler + def_irq_handler ADC2_IRQHandler + def_irq_handler DCDC_IRQHandler + def_irq_handler Reserved86_IRQHandler + def_irq_handler GPIO10_IRQHandler + def_irq_handler GPIO1_INT0_IRQHandler + def_irq_handler GPIO1_INT1_IRQHandler + def_irq_handler GPIO1_INT2_IRQHandler + def_irq_handler GPIO1_INT3_IRQHandler + def_irq_handler GPIO1_INT4_IRQHandler + def_irq_handler GPIO1_INT5_IRQHandler + def_irq_handler GPIO1_INT6_IRQHandler + def_irq_handler GPIO1_INT7_IRQHandler + def_irq_handler GPIO1_Combined_0_15_IRQHandler + def_irq_handler GPIO1_Combined_16_31_IRQHandler + def_irq_handler GPIO2_Combined_0_15_IRQHandler + def_irq_handler GPIO2_Combined_16_31_IRQHandler + def_irq_handler GPIO3_Combined_0_15_IRQHandler + def_irq_handler GPIO3_Combined_16_31_IRQHandler + def_irq_handler GPIO4_Combined_0_15_IRQHandler + def_irq_handler GPIO4_Combined_16_31_IRQHandler + def_irq_handler GPIO5_Combined_0_15_IRQHandler + def_irq_handler GPIO5_Combined_16_31_IRQHandler + def_irq_handler FLEXIO1_DriverIRQHandler + def_irq_handler FLEXIO2_DriverIRQHandler + def_irq_handler WDOG1_IRQHandler + def_irq_handler RTWDOG_IRQHandler + def_irq_handler EWM_IRQHandler + def_irq_handler CCM_1_IRQHandler + def_irq_handler CCM_2_IRQHandler + def_irq_handler GPC_IRQHandler + def_irq_handler SRC_IRQHandler + def_irq_handler Reserved115_IRQHandler + def_irq_handler GPT1_IRQHandler + def_irq_handler GPT2_IRQHandler + def_irq_handler PWM1_0_IRQHandler + def_irq_handler PWM1_1_IRQHandler + def_irq_handler PWM1_2_IRQHandler + def_irq_handler PWM1_3_IRQHandler + def_irq_handler PWM1_FAULT_IRQHandler + def_irq_handler FLEXSPI2_DriverIRQHandler + def_irq_handler FLEXSPI_DriverIRQHandler + def_irq_handler SEMC_IRQHandler + def_irq_handler USDHC1_DriverIRQHandler + def_irq_handler USDHC2_DriverIRQHandler + def_irq_handler USB_OTG2_IRQHandler + def_irq_handler USB_OTG1_IRQHandler + def_irq_handler ENET_DriverIRQHandler + def_irq_handler ENET_1588_Timer_DriverIRQHandler + def_irq_handler XBAR1_IRQ_0_1_IRQHandler + def_irq_handler XBAR1_IRQ_2_3_IRQHandler + def_irq_handler ADC_ETC_IRQ0_IRQHandler + def_irq_handler ADC_ETC_IRQ1_IRQHandler + def_irq_handler ADC_ETC_IRQ2_IRQHandler + def_irq_handler ADC_ETC_ERROR_IRQ_IRQHandler + def_irq_handler PIT_IRQHandler + def_irq_handler ACMP1_IRQHandler + def_irq_handler ACMP2_IRQHandler + def_irq_handler ACMP3_IRQHandler + def_irq_handler ACMP4_IRQHandler + def_irq_handler Reserved143_IRQHandler + def_irq_handler Reserved144_IRQHandler + def_irq_handler ENC1_IRQHandler + def_irq_handler ENC2_IRQHandler + def_irq_handler ENC3_IRQHandler + def_irq_handler ENC4_IRQHandler + def_irq_handler TMR1_IRQHandler + def_irq_handler TMR2_IRQHandler + def_irq_handler TMR3_IRQHandler + def_irq_handler TMR4_IRQHandler + def_irq_handler PWM2_0_IRQHandler + def_irq_handler PWM2_1_IRQHandler + def_irq_handler PWM2_2_IRQHandler + def_irq_handler PWM2_3_IRQHandler + def_irq_handler PWM2_FAULT_IRQHandler + def_irq_handler PWM3_0_IRQHandler + def_irq_handler PWM3_1_IRQHandler + def_irq_handler PWM3_2_IRQHandler + def_irq_handler PWM3_3_IRQHandler + def_irq_handler PWM3_FAULT_IRQHandler + def_irq_handler PWM4_0_IRQHandler + def_irq_handler PWM4_1_IRQHandler + def_irq_handler PWM4_2_IRQHandler + def_irq_handler PWM4_3_IRQHandler + def_irq_handler PWM4_FAULT_IRQHandler + def_irq_handler ENET2_DriverIRQHandler + def_irq_handler ENET2_1588_Timer_DriverIRQHandler + def_irq_handler CAN3_DriverIRQHandler + def_irq_handler Reserved171_IRQHandler + def_irq_handler FLEXIO3_DriverIRQHandler + def_irq_handler GPIO6_7_8_9_IRQHandler + + .end diff --git a/NXP/MIMXRT1064-EVK/app/startup/tx_initialize_low_level.S b/NXP/MIMXRT1064-EVK/app/startup/tx_initialize_low_level.S new file mode 100644 index 00000000..40e3879d --- /dev/null +++ b/NXP/MIMXRT1064-EVK/app/startup/tx_initialize_low_level.S @@ -0,0 +1,207 @@ +/*************************************************************************** + * Copyright (c) 2024 Microsoft Corporation + * Copyright (c) 2026 Eclipse ThreadX contributors + * + * This program and the accompanying materials are made available under the + * terms of the MIT License which is available at + * https://opensource.org/licenses/MIT. + * + * SPDX-License-Identifier: MIT + * + * Contributors: + * Ali Eissa - 2026 NXP i.MX RT1064 port. + **************************************************************************/ + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** ThreadX Component */ +/** */ +/** Initialize */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + + .global _tx_thread_system_stack_ptr + .global _tx_initialize_unused_memory + .global __RAM_segment_used_end__ + .global _tx_timer_interrupt + .global _vectors + .global __tx_NMIHandler // NMI + .global __tx_BadHandler // HardFault + .global __tx_SVCallHandler // SVCall + .global __tx_DBGHandler // Monitor + .global __tx_PendSVHandler // PendSV + .global __tx_SysTickHandler // SysTick + .global __tx_IntHandler // Int 0 + +SYSTICK_CYCLES_HW = ((600000000 / 100) - 1) // 5,999,999 cycles: 600 MHz on real silicon -> 100 Hz +SYSTICK_CYCLES_RENODE = ((72000000 / 100) - 1) // 719,999 cycles: 72 MHz in Renode NVIC -> 100 Hz + + .text + .align 4 + .syntax unified + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_initialize_low_level Cortex-M7/GNU */ +/* 6.4.0 */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function is responsible for any low-level processor */ +/* initialization, including setting up interrupt vectors, setting */ +/* up a periodic timer interrupt source, saving the system stack */ +/* pointer for use in ISR processing later, and finding the first */ +/* available RAM memory address for tx_application_define. */ +/* */ +/* INPUT */ +/* */ +/* None */ +/* */ +/* OUTPUT */ +/* */ +/* None */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* CALLED BY */ +/* */ +/* _tx_initialize_kernel_enter ThreadX entry function */ +/* */ +/**************************************************************************/ + .global _tx_initialize_low_level + .thumb_func +_tx_initialize_low_level: + + /* Disable interrupts during ThreadX initialization. */ + CPSID i + + /* Set base of available memory to end of non-initialised RAM area. */ + LDR r0, =_tx_initialize_unused_memory // Build address of unused memory pointer + LDR r1, =__RAM_segment_used_end__ // Build first free address + ADD r1, r1, #4 // + STR r1, [r0] // Setup first unused memory pointer + + /* Setup Vector Table Offset Register. */ + MOV r0, #0xE000E000 // Build address of NVIC registers + LDR r1, =_vectors // Pickup address of vector table + STR r1, [r0, #0xD08] // Set vector table address + + /* Set system stack pointer from vector value. */ + LDR r0, =_tx_thread_system_stack_ptr // Build address of system stack pointer + LDR r1, =_vectors // Pickup address of vector table + LDR r1, [r1] // Pickup reset stack pointer + STR r1, [r0] // Save system stack pointer + + /* Enable the DWT cycle count register if DWT hardware is present (physical silicon). */ + LDR r1, =0xE000ED90 // MPU->TYPE register + LDR r1, [r1] + LSRS r1, r1, #8 + AND r1, r1, #0xFF // Extract DREGION field + CMP r1, #12 // Physical silicon has 16 regions, Renode has 8 + BLT .Lskip_dwt + LDR r0, =0xE0001000 // Build address of DWT register + LDR r1, [r0] // Pickup the current value + ORR r1, r1, #1 // Set the CYCCNTENA bit + STR r1, [r0] // Enable the cycle count register +.Lskip_dwt: + + /* Configure SysTick reload: detect Renode (72 MHz NVIC clock) vs physical silicon (600 MHz core clock). */ + LDR r1, =0xE000ED90 // MPU->TYPE register + LDR r1, [r1] + LSRS r1, r1, #8 + AND r1, r1, #0xFF // Extract DREGION field + CMP r1, #12 + BLT .Lrenode_systick + LDR r1, =SYSTICK_CYCLES_HW // 600 MHz clock -> reload for 100 Hz + B .Lset_systick +.Lrenode_systick: + LDR r1, =SYSTICK_CYCLES_RENODE // 72 MHz clock -> reload for 100 Hz +.Lset_systick: + MOV r0, #0xE000E000 // Build address of NVIC registers + STR r1, [r0, #0x14] // Setup SysTick Reload Value + MOV r1, #0x7 // Build SysTick Control Enable Value (CLKSOURCE|TICKINT|ENABLE) + STR r1, [r0, #0x10] // Setup SysTick Control + + /* Configure handler priorities (upper 4 bits implemented on Cortex-M7, mask 0xF0). */ + LDR r1, =0x00000000 // Rsrv, UsgF, BusF, MemM + STR r1, [r0, #0xD18] // Setup System Handlers 4-7 Priority Registers + LDR r1, =0xF0000000 // SVCl, Rsrv, Rsrv, Rsrv + STR r1, [r0, #0xD1C] // Setup System Handlers 8-11 Priority Registers + // Note: SVC must be lowest priority (0xF0 for 4-bit NVIC) + LDR r1, =0x40F00000 // SysT (0x40), PnSV (0xF0), Rsrv, DbgM + STR r1, [r0, #0xD20] // Setup System Handlers 12-15 Priority Registers + // Note: PnSV must be lowest priority (0xF0 for 4-bit NVIC) + + /* Return to caller. */ + BX lr + +/* Define shells for each of the unused vectors. */ + .global __tx_BadHandler + .thumb_func +__tx_BadHandler: + B __tx_BadHandler + +/* Catch HardFault */ + .global __tx_HardfaultHandler + .thumb_func +__tx_HardfaultHandler: + B __tx_HardfaultHandler + +/* Catch SVC */ + .global __tx_SVCallHandler + .thumb_func +__tx_SVCallHandler: + B __tx_SVCallHandler + +/* Generic interrupt handler template */ + .global __tx_IntHandler + .thumb_func +__tx_IntHandler: + PUSH {r0, lr} +#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY + BL _tx_execution_isr_enter // Call the ISR enter function +#endif + /* Do interrupt handler work here */ +#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY + BL _tx_execution_isr_exit // Call the ISR exit function +#endif + POP {r0, lr} + BX lr + +/* System Tick timer interrupt handler */ + .global __tx_SysTickHandler + .global SysTick_Handler + .thumb_func +__tx_SysTickHandler: + .thumb_func +SysTick_Handler: + PUSH {r0, lr} +#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY + BL _tx_execution_isr_enter // Call the ISR enter function +#endif + BL _tx_timer_interrupt +#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY + BL _tx_execution_isr_exit // Call the ISR exit function +#endif + POP {r0, lr} + BX lr + +/* NMI, DBG handlers */ + .global __tx_NMIHandler + .thumb_func +__tx_NMIHandler: + B __tx_NMIHandler + + .global __tx_DBGHandler + .thumb_func +__tx_DBGHandler: + B __tx_DBGHandler diff --git a/NXP/MIMXRT1064-EVK/app/syscalls.c b/NXP/MIMXRT1064-EVK/app/syscalls.c new file mode 100644 index 00000000..fa3d9e88 --- /dev/null +++ b/NXP/MIMXRT1064-EVK/app/syscalls.c @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2026 Eclipse ThreadX contributors + * + * 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 NXP i.MX RT1064 port. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +char *__env[1] = { 0 }; +char **environ = __env; + +void initialise_monitor_handles(void) +{ +} + +int _getpid(void) +{ + return 1; +} + +int _kill(int pid, int sig) +{ + (void)pid; + (void)sig; + errno = EINVAL; + return -1; +} + +void _exit(int status) +{ + _kill(status, -1); + while (1) {} +} + +int _close(int file) +{ + (void)file; + return -1; +} + +int _fstat(int file, struct stat *st) +{ + (void)file; + st->st_mode = S_IFCHR; + return 0; +} + +int _isatty(int file) +{ + (void)file; + return 1; +} + +int _lseek(int file, int ptr, int dir) +{ + (void)file; + (void)ptr; + (void)dir; + return 0; +} + +int _open(char *path, int flags, ...) +{ + (void)path; + (void)flags; + return -1; +} + +int _wait(int *status) +{ + (void)status; + errno = ECHILD; + return -1; +} + +int _unlink(char *name) +{ + (void)name; + errno = ENOENT; + return -1; +} + +int _times(struct tms *buf) +{ + (void)buf; + return -1; +} + +int _stat(char *file, struct stat *st) +{ + (void)file; + st->st_mode = S_IFCHR; + return 0; +} + +int _link(char *old, char *new) +{ + (void)old; + (void)new; + errno = EMLINK; + return -1; +} + +int _fork(void) +{ + errno = EAGAIN; + return -1; +} + +int _execve(char *name, char **argv, char **env) +{ + (void)name; + (void)argv; + (void)env; + errno = ENOMEM; + return -1; +} diff --git a/NXP/MIMXRT1064-EVK/app/sysmem.c b/NXP/MIMXRT1064-EVK/app/sysmem.c new file mode 100644 index 00000000..98235ab8 --- /dev/null +++ b/NXP/MIMXRT1064-EVK/app/sysmem.c @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2026 Eclipse ThreadX contributors + * + * 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 NXP i.MX RT1064 port. + */ + +#include +#include +#include + +/** + * Pointer to the current high watermark of the heap usage + */ +static uint8_t *__sbrk_heap_end = NULL; + +/** + * @brief _sbrk() allocates memory to the newlib heap and is used by malloc. + */ +void *_sbrk(ptrdiff_t incr) +{ + extern uint8_t _end; + extern uint8_t __StackLimit; + const uint8_t *max_heap = &__StackLimit; + uint8_t *prev_heap_end; + + /* Initialize heap end at first call */ + if (NULL == __sbrk_heap_end) + { + __sbrk_heap_end = &_end; + } + + /* Protect heap from growing into stack */ + if (__sbrk_heap_end + incr > max_heap) + { + errno = ENOMEM; + return (void *)-1; + } + + prev_heap_end = __sbrk_heap_end; + __sbrk_heap_end += incr; + + return (void *)prev_heap_end; +} diff --git a/NXP/MIMXRT1064-EVK/lib/threadx/tx_user.h b/NXP/MIMXRT1064-EVK/lib/threadx/tx_user.h index c9258245..b6f7d03c 100644 --- a/NXP/MIMXRT1064-EVK/lib/threadx/tx_user.h +++ b/NXP/MIMXRT1064-EVK/lib/threadx/tx_user.h @@ -20,7 +20,7 @@ /* System tick frequency in Hz (typically 100 or 1000) */ #ifndef TX_TIMER_TICKS_PER_SECOND -#define TX_TIMER_TICKS_PER_SECOND 1000 +#define TX_TIMER_TICKS_PER_SECOND 100 #endif #endif /* TX_USER_H */ diff --git a/NXP/MIMXRT1064-EVK/renode/mimxrt1064-evk.resc b/NXP/MIMXRT1064-EVK/renode/mimxrt1064-evk.resc new file mode 100644 index 00000000..40c039a3 --- /dev/null +++ b/NXP/MIMXRT1064-EVK/renode/mimxrt1064-evk.resc @@ -0,0 +1,21 @@ +:name: MIMXRT1064-EVK ThreadX Demo +:description: This script runs the Eclipse ThreadX demo on NXP i.MX RT1064-EVK. + +mach create "mimxrt1064-evk" +machine LoadPlatformDescription @platforms/boards/mimxrt1064_evk.repl + +$bin?=@$ORIGIN/../build/mimxrt1064_threadx.elf + +showAnalyzer sysbus.lpuart1 + +macro reset +""" + cpu VectorTableOffset 0x70002000 + sysbus LoadELF $bin + cpu PC `sysbus ReadDoubleWord 0x70002004` + cpu SP `sysbus ReadDoubleWord 0x70002000` +""" + +runMacro $reset + +start diff --git a/NXP/MIMXRT1064-EVK/scripts/fetch_sdk.ps1 b/NXP/MIMXRT1064-EVK/scripts/fetch_sdk.ps1 index 8965cb87..1a0484c0 100644 --- a/NXP/MIMXRT1064-EVK/scripts/fetch_sdk.ps1 +++ b/NXP/MIMXRT1064-EVK/scripts/fetch_sdk.ps1 @@ -33,6 +33,8 @@ New-Item -ItemType Directory -Path $UtilitiesDir -Force | Out-Null New-Item -ItemType Directory -Path (Join-Path $ComponentsDir "uart") -Force | Out-Null New-Item -ItemType Directory -Path $BoardFilesDir -Force | Out-Null New-Item -ItemType Directory -Path $CmsisIncludeDest -Force | Out-Null +$AppStartupDir = Join-Path $BoardDir "app/startup" +New-Item -ItemType Directory -Path $AppStartupDir -Force | Out-Null if (Test-Path $TempDir) { Remove-Item -Path $TempDir -Recurse -Force } New-Item -ItemType Directory -Path $TempDir -Force | Out-Null @@ -125,6 +127,21 @@ try { Write-Host "[OK] NXP Device, Driver, Utility, and Component files copied" Write-Host "" + # Helper function to download with retries for GitHub CDN resilience + function Download-WithRetry { + param([string]$Uri, [string]$OutFile, [int]$MaxAttempts = 4) + for ($i = 1; $i -le $MaxAttempts; $i++) { + try { + Invoke-WebRequest -Uri $Uri -OutFile $OutFile -UseBasicParsing -TimeoutSec 30 + return + } + catch { + if ($i -eq $MaxAttempts) { throw $_ } + Start-Sleep -Seconds 2 + } + } + } + # 2. Download EVK-MIMXRT1064 Board Initialization Files from official NXP mcuxsdk-examples $rawBase = "https://raw.githubusercontent.com/nxp-mcuxpresso/mcuxsdk-examples/main/_boards/evkmimxrt1064" $boardFiles = @( @@ -137,16 +154,28 @@ try { @{ Remote = "$rawBase/dcd.c"; Local = "dcd.c" }, @{ Remote = "$rawBase/dcd.h"; Local = "dcd.h" }, @{ Remote = "$rawBase/xip/evkmimxrt1064_flexspi_nor_config.c"; Local = "evkmimxrt1064_flexspi_nor_config.c" }, - @{ Remote = "$rawBase/xip/evkmimxrt1064_flexspi_nor_config.h"; Local = "evkmimxrt1064_flexspi_nor_config.h" }, - @{ Remote = "$rawBase/linker/mcux/MIMXRT1064xxxxx_flexspi_nor.ld"; Local = "MIMXRT1064xxxxx_flexspi_nor.ld" } + @{ Remote = "$rawBase/xip/evkmimxrt1064_flexspi_nor_config.h"; Local = "evkmimxrt1064_flexspi_nor_config.h" } ) Write-Host "[INFO] Downloading EVK-MIMXRT1064 board support files..." foreach ($item in $boardFiles) { $dest = Join-Path $BoardFilesDir $item.Local - Invoke-WebRequest -Uri $item.Remote -OutFile $dest -UseBasicParsing + Download-WithRetry -Uri $item.Remote -OutFile $dest } - Write-Host "[OK] Board support files downloaded" + + # Download official GNU GCC Linker Script & Startup File from official NXP mcux-sdk repository + Write-Host "[INFO] Downloading official NXP GNU GCC Linker Script and Startup File..." + $nxpGccBase = "https://raw.githubusercontent.com/nxp-mcuxpresso/mcux-sdk/main/devices/MIMXRT1064/gcc" + $ldDestBoard = Join-Path $BoardFilesDir "MIMXRT1064xxxxx_flexspi_nor.ld" + $ldDestApp = Join-Path $AppStartupDir "MIMXRT1064xxxxx_flexspi_nor.ld" + $startupDest = Join-Path $AppStartupDir "startup_mimxrt1064.S" + + Download-WithRetry -Uri "$nxpGccBase/MIMXRT1064xxxxx_flexspi_nor.ld" -OutFile $ldDestBoard + Copy-Item -Path $ldDestBoard -Destination $ldDestApp -Force + + Download-WithRetry -Uri "$nxpGccBase/startup_MIMXRT1064.S" -OutFile $startupDest + + Write-Host "[OK] Board support and official GCC startup/linker files downloaded" Write-Host "" # 3. Fetch CMSIS Core headers (standard ARM CMSIS-Core include files) diff --git a/NXP/MIMXRT1064-EVK/scripts/fetch_sdk.sh b/NXP/MIMXRT1064-EVK/scripts/fetch_sdk.sh index 50f2c45c..f4c6b3aa 100644 --- a/NXP/MIMXRT1064-EVK/scripts/fetch_sdk.sh +++ b/NXP/MIMXRT1064-EVK/scripts/fetch_sdk.sh @@ -22,6 +22,7 @@ UTILITIES_DIR="${LIB_DIR}/utilities" COMPONENTS_DIR="${LIB_DIR}/components" BOARD_FILES_DIR="${LIB_DIR}/board" CMSIS_INCLUDE_DEST="${LIB_DIR}/CMSIS/Include" +APP_STARTUP_DIR="${BOARD_DIR}/app/startup" TEMP_DIR="${BOARD_DIR}/temp_fetch" echo "==========================================" @@ -38,6 +39,7 @@ mkdir -p "${UTILITIES_DIR}" mkdir -p "${COMPONENTS_DIR}/uart" mkdir -p "${BOARD_FILES_DIR}" mkdir -p "${CMSIS_INCLUDE_DEST}" +mkdir -p "${APP_STARTUP_DIR}" rm -rf "${TEMP_DIR}" mkdir -p "${TEMP_DIR}" @@ -110,9 +112,15 @@ curl -fsSL "${RAW_BASE}/dcd.c" -o "${BOARD_FILES_DIR}/dcd.c" curl -fsSL "${RAW_BASE}/dcd.h" -o "${BOARD_FILES_DIR}/dcd.h" curl -fsSL "${RAW_BASE}/xip/evkmimxrt1064_flexspi_nor_config.c" -o "${BOARD_FILES_DIR}/evkmimxrt1064_flexspi_nor_config.c" curl -fsSL "${RAW_BASE}/xip/evkmimxrt1064_flexspi_nor_config.h" -o "${BOARD_FILES_DIR}/evkmimxrt1064_flexspi_nor_config.h" -curl -fsSL "${RAW_BASE}/linker/mcux/MIMXRT1064xxxxx_flexspi_nor.ld" -o "${BOARD_FILES_DIR}/MIMXRT1064xxxxx_flexspi_nor.ld" -echo "[OK] Board support files downloaded" +echo "[INFO] Downloading official NXP GNU GCC Linker Script and Startup File..." +NXP_GCC_BASE="https://raw.githubusercontent.com/nxp-mcuxpresso/mcux-sdk/main/devices/MIMXRT1064/gcc" +curl --retry 3 -fsSL "${NXP_GCC_BASE}/MIMXRT1064xxxxx_flexspi_nor.ld" -o "${BOARD_FILES_DIR}/MIMXRT1064xxxxx_flexspi_nor.ld" +cp "${BOARD_FILES_DIR}/MIMXRT1064xxxxx_flexspi_nor.ld" "${APP_STARTUP_DIR}/MIMXRT1064xxxxx_flexspi_nor.ld" + +curl --retry 3 -fsSL "${NXP_GCC_BASE}/startup_MIMXRT1064.S" -o "${APP_STARTUP_DIR}/startup_mimxrt1064.S" + +echo "[OK] Board support and official GCC startup/linker files downloaded" echo "" # 3. Fetch CMSIS Core headers diff --git a/NXP/MIMXRT1064-EVK/scripts/simulate.ps1 b/NXP/MIMXRT1064-EVK/scripts/simulate.ps1 new file mode 100644 index 00000000..3d2ba2ad --- /dev/null +++ b/NXP/MIMXRT1064-EVK/scripts/simulate.ps1 @@ -0,0 +1,47 @@ +# Copyright (c) 2026 Eclipse ThreadX contributors +# +# 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. + +$BoardDir = Resolve-Path "$PSScriptRoot/.." +$ElfPath = Join-Path $BoardDir "build/mimxrt1064_threadx.elf" +$RescRelPath = "renode/mimxrt1064-evk.resc" +$RescFullPath = Join-Path $BoardDir $RescRelPath + +if (-not (Test-Path $ElfPath)) { + Write-Error "Binary $ElfPath not found. Please build the project first using .\scripts\build.ps1" + exit 1 +} + +# Find Renode executable +$RenodeExe = (Get-Command renode -ErrorAction SilentlyContinue).Source +if (-not $RenodeExe -and (Test-Path "C:\Program Files\Renode\renode.exe")) { + $RenodeExe = "C:\Program Files\Renode\renode.exe" +} + +if (-not $RenodeExe) { + Write-Error "Renode was not found in PATH or at 'C:\Program Files\Renode\renode.exe'." + exit 1 +} + +Write-Host "==========================================" +Write-Host "Starting Renode Simulation" +Write-Host "==========================================" +Write-Host "Renode: $RenodeExe" +Write-Host "Script: $RescFullPath" +Write-Host "Target ELF: $ElfPath" +Write-Host "" +Write-Host "Opening Renode Monitor and LPUART1 terminal analyzer..." +Write-Host "To exit Renode, type 'quit' in the Renode Monitor or close the window." +Write-Host "==========================================" + +Set-Location $BoardDir + +# Pass relative script path with quotes to avoid tokenization errors when workspace contains spaces +& $RenodeExe -e "include @`"$RescRelPath`"" diff --git a/NXP/MIMXRT1064-EVK/scripts/simulate.sh b/NXP/MIMXRT1064-EVK/scripts/simulate.sh new file mode 100644 index 00000000..f47a8a43 --- /dev/null +++ b/NXP/MIMXRT1064-EVK/scripts/simulate.sh @@ -0,0 +1,43 @@ +#!/usr/bin/env bash +# Copyright (c) 2026 Eclipse ThreadX contributors +# +# 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. + +set -e + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +BOARD_DIR="$(cd "${SCRIPT_DIR}/.." && pwd)" +ELF_PATH="${BOARD_DIR}/build/mimxrt1064_threadx.elf" +RESC_REL_PATH="renode/mimxrt1064-evk.resc" + +if [ ! -f "${ELF_PATH}" ]; then + echo "[ERROR] Binary ${ELF_PATH} not found. Please build first using ./scripts/build.sh" + exit 1 +fi + +RENODE_CMD="renode" +if ! command -v renode &> /dev/null; then + if [ -f "/opt/renode/renode" ]; then + RENODE_CMD="/opt/renode/renode" + else + echo "[ERROR] Renode was not found in PATH." + exit 1 + fi +fi + +echo "==========================================" +echo "Starting Renode Simulation" +echo "==========================================" +echo "Script: ${BOARD_DIR}/${RESC_REL_PATH}" +echo "Target ELF: ${ELF_PATH}" +echo "" + +cd "${BOARD_DIR}" +"${RENODE_CMD}" -e "include @\"${RESC_REL_PATH}\"" From 35d87486c0dc0ad94b21f07b3ba60ef1a293de6c Mon Sep 17 00:00:00 2001 From: Ali Eissa Date: Thu, 10 Sep 2026 07:04:42 +0400 Subject: [PATCH 03/11] fetch sdk bug fixes Signed-off-by: Ali Eissa Assisted-by: Google DeepMind Antigravity --- .../app/startup/MIMXRT1064xxxxx_flexspi_nor.ld | 3 +-- NXP/MIMXRT1064-EVK/app/startup/startup_mimxrt1064.S | 12 ++++-------- NXP/MIMXRT1064-EVK/scripts/fetch_sdk.ps1 | 13 +++++-------- NXP/MIMXRT1064-EVK/scripts/fetch_sdk.sh | 8 +++----- 4 files changed, 13 insertions(+), 23 deletions(-) diff --git a/NXP/MIMXRT1064-EVK/app/startup/MIMXRT1064xxxxx_flexspi_nor.ld b/NXP/MIMXRT1064-EVK/app/startup/MIMXRT1064xxxxx_flexspi_nor.ld index e5dd1d68..8e79f28c 100644 --- a/NXP/MIMXRT1064-EVK/app/startup/MIMXRT1064xxxxx_flexspi_nor.ld +++ b/NXP/MIMXRT1064-EVK/app/startup/MIMXRT1064xxxxx_flexspi_nor.ld @@ -255,7 +255,7 @@ SECTIONS . += HEAP_SIZE; __HeapLimit = .; __heap_limit = .; /* Add for _sbrk */ - __RAM_segment_used_end__ = .; /* Used by ThreadX for first unused memory */ + __RAM_segment_used_end__ = .; } > m_data .stack : @@ -268,7 +268,6 @@ SECTIONS __StackTop = ORIGIN(m_data) + LENGTH(m_data); __StackLimit = __StackTop - STACK_SIZE; PROVIDE(__stack = __StackTop); - PROVIDE(_estack = __StackTop); .ARM.attributes 0 : { *(.ARM.attributes) } diff --git a/NXP/MIMXRT1064-EVK/app/startup/startup_mimxrt1064.S b/NXP/MIMXRT1064-EVK/app/startup/startup_mimxrt1064.S index a2137e4f..95442231 100644 --- a/NXP/MIMXRT1064-EVK/app/startup/startup_mimxrt1064.S +++ b/NXP/MIMXRT1064-EVK/app/startup/startup_mimxrt1064.S @@ -19,14 +19,14 @@ .section .isr_vector, "a" .align 2 .globl __isr_vector - .globl __VECTOR_TABLE - .globl __Vectors .globl _vectors + .globl __Vectors + .globl __VECTOR_TABLE .globl g_pfnVectors __isr_vector: -__VECTOR_TABLE: -__Vectors: _vectors: +__Vectors: +__VECTOR_TABLE: g_pfnVectors: .long __StackTop /* Top of Stack */ .long Reset_Handler /* Reset Handler */ @@ -406,10 +406,6 @@ Reset_Handler: blt .LC4 #endif /* __STARTUP_INITIALIZE_NONCACHEDATA */ -#ifndef __STARTUP_CLEAR_BSS -#define __STARTUP_CLEAR_BSS -#endif - #ifdef __STARTUP_CLEAR_BSS /* This part of work usually is done in C library startup code. Otherwise, * define this macro to enable it in this startup. diff --git a/NXP/MIMXRT1064-EVK/scripts/fetch_sdk.ps1 b/NXP/MIMXRT1064-EVK/scripts/fetch_sdk.ps1 index 1a0484c0..420f7ef9 100644 --- a/NXP/MIMXRT1064-EVK/scripts/fetch_sdk.ps1 +++ b/NXP/MIMXRT1064-EVK/scripts/fetch_sdk.ps1 @@ -163,19 +163,16 @@ try { Download-WithRetry -Uri $item.Remote -OutFile $dest } - # Download official GNU GCC Linker Script & Startup File from official NXP mcux-sdk repository - Write-Host "[INFO] Downloading official NXP GNU GCC Linker Script and Startup File..." + # Download official GNU GCC Linker Script & Startup File for reference in lib/mcux-sdk/board/ + Write-Host "[INFO] Downloading official NXP GNU GCC Linker Script and Startup File into board directory..." $nxpGccBase = "https://raw.githubusercontent.com/nxp-mcuxpresso/mcux-sdk/main/devices/MIMXRT1064/gcc" $ldDestBoard = Join-Path $BoardFilesDir "MIMXRT1064xxxxx_flexspi_nor.ld" - $ldDestApp = Join-Path $AppStartupDir "MIMXRT1064xxxxx_flexspi_nor.ld" - $startupDest = Join-Path $AppStartupDir "startup_mimxrt1064.S" + $startupDestBoard = Join-Path $BoardFilesDir "startup_MIMXRT1064.S" Download-WithRetry -Uri "$nxpGccBase/MIMXRT1064xxxxx_flexspi_nor.ld" -OutFile $ldDestBoard - Copy-Item -Path $ldDestBoard -Destination $ldDestApp -Force + Download-WithRetry -Uri "$nxpGccBase/startup_MIMXRT1064.S" -OutFile $startupDestBoard - Download-WithRetry -Uri "$nxpGccBase/startup_MIMXRT1064.S" -OutFile $startupDest - - Write-Host "[OK] Board support and official GCC startup/linker files downloaded" + Write-Host "[OK] Board support and official GCC reference files downloaded" Write-Host "" # 3. Fetch CMSIS Core headers (standard ARM CMSIS-Core include files) diff --git a/NXP/MIMXRT1064-EVK/scripts/fetch_sdk.sh b/NXP/MIMXRT1064-EVK/scripts/fetch_sdk.sh index f4c6b3aa..b0a6e439 100644 --- a/NXP/MIMXRT1064-EVK/scripts/fetch_sdk.sh +++ b/NXP/MIMXRT1064-EVK/scripts/fetch_sdk.sh @@ -113,14 +113,12 @@ curl -fsSL "${RAW_BASE}/dcd.h" -o "${BOARD_FILES_DIR}/dcd.h" curl -fsSL "${RAW_BASE}/xip/evkmimxrt1064_flexspi_nor_config.c" -o "${BOARD_FILES_DIR}/evkmimxrt1064_flexspi_nor_config.c" curl -fsSL "${RAW_BASE}/xip/evkmimxrt1064_flexspi_nor_config.h" -o "${BOARD_FILES_DIR}/evkmimxrt1064_flexspi_nor_config.h" -echo "[INFO] Downloading official NXP GNU GCC Linker Script and Startup File..." +echo "[INFO] Downloading official NXP GNU GCC Linker Script and Startup File into board directory..." NXP_GCC_BASE="https://raw.githubusercontent.com/nxp-mcuxpresso/mcux-sdk/main/devices/MIMXRT1064/gcc" curl --retry 3 -fsSL "${NXP_GCC_BASE}/MIMXRT1064xxxxx_flexspi_nor.ld" -o "${BOARD_FILES_DIR}/MIMXRT1064xxxxx_flexspi_nor.ld" -cp "${BOARD_FILES_DIR}/MIMXRT1064xxxxx_flexspi_nor.ld" "${APP_STARTUP_DIR}/MIMXRT1064xxxxx_flexspi_nor.ld" +curl --retry 3 -fsSL "${NXP_GCC_BASE}/startup_MIMXRT1064.S" -o "${BOARD_FILES_DIR}/startup_MIMXRT1064.S" -curl --retry 3 -fsSL "${NXP_GCC_BASE}/startup_MIMXRT1064.S" -o "${APP_STARTUP_DIR}/startup_mimxrt1064.S" - -echo "[OK] Board support and official GCC startup/linker files downloaded" +echo "[OK] Board support and official GCC reference files downloaded" echo "" # 3. Fetch CMSIS Core headers From 7dec08d991f0425bb53a26d1d88fa208119975d3 Mon Sep 17 00:00:00 2001 From: Ali Eissa Date: Thu, 10 Sep 2026 08:01:45 +0400 Subject: [PATCH 04/11] NXP i.MX RT1064-EVK: GPIO & Peripheral Indicator Demo Signed-off-by: Ali Eissa Assisted-by: Google DeepMind Antigravity --- NXP/MIMXRT1064-EVK/README.md | 33 +++++++++++++++-- NXP/MIMXRT1064-EVK/app/board_init.c | 20 +++++++++-- NXP/MIMXRT1064-EVK/app/main.c | 9 +++-- NXP/MIMXRT1064-EVK/renode/mimxrt1064-evk.repl | 35 +++++++++++++++++++ NXP/MIMXRT1064-EVK/renode/mimxrt1064-evk.resc | 6 ++-- 5 files changed, 94 insertions(+), 9 deletions(-) create mode 100644 NXP/MIMXRT1064-EVK/renode/mimxrt1064-evk.repl diff --git a/NXP/MIMXRT1064-EVK/README.md b/NXP/MIMXRT1064-EVK/README.md index c972249e..e625089f 100644 --- a/NXP/MIMXRT1064-EVK/README.md +++ b/NXP/MIMXRT1064-EVK/README.md @@ -13,7 +13,8 @@ The project is designed to run seamlessly both in the **Antmicro Renode** simula * **Flash Memory**: 4 MB internal FlexSPI NOR Flash (XIP) * **Internal SRAM**: 1 MB on-chip RAM (Configurable as ITCM, DTCM, and OCRAM) * **Debug Serial Console**: LPUART1 (115,200 baud, 8N1) -* **User LED**: GPIO9 Pin 3 (`GPIO_AD_B0_09`) / User LED (Green) +* **User LED**: GPIO1 Pin 9 (`GPIO_AD_B0_09`) / User LED D18 (Green) +* **User Button**: GPIO5 Pin 0 (SW8 WAKEUP button) * **Virtual Networking**: ENET1 (10/100M Fast Ethernet MAC via KSZ8081 PHY) --- @@ -25,17 +26,30 @@ NXP/MIMXRT1064-EVK/ ├── CMakeLists.txt # Top-level CMake build configuration ├── NOTICE.md # Third-party licensing notices (NXP BSD-3 & CMSIS) ├── README.md # This documentation file +├── app/ +│ ├── main.c # ThreadX application entry, Heartbeat & Worker threads +│ ├── board_init.c / .h # Clocks (600 MHz), MPU, pin muxing & User LED init +│ ├── console.c / .h # LPUART1 serial driver & POSIX printf retargeting +│ ├── syscalls.c / sysmem.c # Minimal C runtime system call stubs +│ └── startup/ +│ ├── startup_mimxrt1064.S # NXP vector table & reset handler +│ ├── tx_initialize_low_level.S # ThreadX Cortex-M7 low-level init & SysTick +│ └── MIMXRT1064xxxxx_flexspi_nor.ld # FlexSPI NOR XIP GNU linker script ├── cmake/ │ ├── arm-gcc-cortex-m7.cmake # CPU architecture and FPU definitions │ ├── arm-gcc-cortex-toolchain.cmake # GNU toolchain discovery and compiler flags │ └── utilities.cmake # Elf-to-bin/hex conversion and linker macros ├── lib/ │ ├── threadx/ -│ │ └── tx_user.h # ThreadX configuration (hardware FPU enabled) +│ │ └── tx_user.h # ThreadX configuration (hardware FPU enabled, 100 Hz tick) │ └── mcux-sdk/ # Official NXP SDK drivers (fetched via script) +├── renode/ +│ ├── mimxrt1064-evk.repl # Board platform description (memory, LED, button) +│ └── mimxrt1064-evk.resc # Renode simulation script (LPUART1 analyzer & LED logging) └── scripts/ ├── fetch_sdk.ps1 / .sh # Download official NXP drivers, device headers & CMSIS - └── build.ps1 / .sh # One-command build script with Ninja/CMake + ├── build.ps1 / .sh # One-command build script with Ninja/CMake + └── simulate.ps1 / .sh # Launch Renode simulation with serial monitor ``` --- @@ -80,6 +94,19 @@ Compile the application, vendor drivers, and Eclipse ThreadX kernel: ./scripts/build.sh --rebuild ``` +### 3. Run the Simulation in Renode +Launch the interactive Renode simulation: + +* **On Windows (PowerShell)**: + ```powershell + .\scripts\simulate.ps1 + ``` +* **On Linux / macOS (Bash)**: + ```bash + chmod +x ./scripts/simulate.sh + ./scripts/simulate.sh + ``` + --- ## Hardware Verification Status diff --git a/NXP/MIMXRT1064-EVK/app/board_init.c b/NXP/MIMXRT1064-EVK/app/board_init.c index 9586e39c..472a3c9b 100644 --- a/NXP/MIMXRT1064-EVK/app/board_init.c +++ b/NXP/MIMXRT1064-EVK/app/board_init.c @@ -13,6 +13,8 @@ #include "board_init.h" #include "console.h" +#include "fsl_iomuxc.h" +#include "fsl_gpio.h" void board_init(void) { @@ -25,9 +27,23 @@ void board_init(void) /* 2. Configure Pin Muxing (UART1 TX/RX pins) */ BOARD_InitPins(); - /* 3. Configure System Clocks (600 MHz AHB core clock) */ + /* 3. Configure User LED Pin Muxing (GPIO_AD_B0_09 -> GPIO1_IO09) */ + CLOCK_EnableClock(kCLOCK_Iomuxc); + IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B0_09_GPIO1_IO09, 0U); + IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_B0_09_GPIO1_IO09, 0x10B0u); + + /* 4. Configure System Clocks (600 MHz AHB core clock) */ BOARD_BootClockRUN(); - /* 4. Initialize LPUART1 Serial Console at 115200 baud */ + /* 5. Initialize User LED GPIO (GPIO1 Pin 9, output, initial state OFF) */ + gpio_pin_config_t led_config = { + kGPIO_DigitalOutput, + 0, + kGPIO_NoIntmode + }; + GPIO_PinInit(BOARD_USER_LED_GPIO, BOARD_USER_LED_GPIO_PIN, &led_config); + USER_LED_OFF(); + + /* 6. Initialize LPUART1 Serial Console at 115200 baud */ console_init(); } diff --git a/NXP/MIMXRT1064-EVK/app/main.c b/NXP/MIMXRT1064-EVK/app/main.c index c3807225..b313f404 100644 --- a/NXP/MIMXRT1064-EVK/app/main.c +++ b/NXP/MIMXRT1064-EVK/app/main.c @@ -112,6 +112,7 @@ static void heartbeat_thread_entry(ULONG thread_input) { (void)thread_input; ULONG count = 0; + uint8_t led_state = 0; printf("[Heartbeat Thread] Started.\r\n"); @@ -121,8 +122,12 @@ static void heartbeat_thread_entry(ULONG thread_input) tx_thread_sleep(50); count++; - printf("[Heartbeat Thread] Heartbeat #%lu (System Tick: %lu)\r\n", - count, tx_time_get()); + /* Toggle User LED (D18) on GPIO1 Pin 9 */ + USER_LED_TOGGLE(); + led_state = !led_state; + + printf("[Heartbeat Thread] Heartbeat #%lu (System Tick: %lu | User LED: %s)\r\n", + count, tx_time_get(), led_state ? "ON" : "OFF"); } } diff --git a/NXP/MIMXRT1064-EVK/renode/mimxrt1064-evk.repl b/NXP/MIMXRT1064-EVK/renode/mimxrt1064-evk.repl new file mode 100644 index 00000000..c15a32ae --- /dev/null +++ b/NXP/MIMXRT1064-EVK/renode/mimxrt1064-evk.repl @@ -0,0 +1,35 @@ +// Copyright (c) 2026 Eclipse ThreadX contributors +// +// 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 +// +// Platform description for NXP i.MX RT1064-EVK (Simulated in Renode). + +using "platforms/cpus/imxrt1064.repl" + +// External SDRAM (32 MB @ 0x80000000) +sdram0: Memory.MappedMemory @ sysbus 0x80000000 + size: 0x2000000 + +// External/On-chip FlexSPI NOR Flash (4 MB @ 0x70000000) +flash_mem: Memory.MappedMemory @ sysbus 0x70000000 + size: 0x400000 + +// User Button SW8 (WAKEUP, active low, connected to GPIO5 Pin 0) +user_button: Miscellaneous.Button @ gpio5 + invert: true + -> gpio5@0 + +// User LED D18 (Green, active low, connected to GPIO1 Pin 9) +user_led: Miscellaneous.LED @ gpio1 9 + invert: true + +// On-chip ADCs +adc1: + referenceVoltage: 3.3 + +adc2: + referenceVoltage: 3.3 diff --git a/NXP/MIMXRT1064-EVK/renode/mimxrt1064-evk.resc b/NXP/MIMXRT1064-EVK/renode/mimxrt1064-evk.resc index 40c039a3..ba8f9226 100644 --- a/NXP/MIMXRT1064-EVK/renode/mimxrt1064-evk.resc +++ b/NXP/MIMXRT1064-EVK/renode/mimxrt1064-evk.resc @@ -2,9 +2,11 @@ :description: This script runs the Eclipse ThreadX demo on NXP i.MX RT1064-EVK. mach create "mimxrt1064-evk" -machine LoadPlatformDescription @platforms/boards/mimxrt1064_evk.repl -$bin?=@$ORIGIN/../build/mimxrt1064_threadx.elf +$platform?=$ORIGIN/mimxrt1064-evk.repl +machine LoadPlatformDescription $platform + +$bin?=$ORIGIN/../build/mimxrt1064_threadx.elf showAnalyzer sysbus.lpuart1 From 9ca5b1e81450fd5d21e7e6a94eb1a18e9b48716b Mon Sep 17 00:00:00 2001 From: Ali Eissa Date: Sat, 12 Sep 2026 22:27:36 +0400 Subject: [PATCH 05/11] small bug fix: renode user_led return value Signed-off-by: Ali Eissa Assisted-by: Google DeepMind Antigravity --- NXP/MIMXRT1064-EVK/renode/mimxrt1064-evk.repl | 3 +++ 1 file changed, 3 insertions(+) diff --git a/NXP/MIMXRT1064-EVK/renode/mimxrt1064-evk.repl b/NXP/MIMXRT1064-EVK/renode/mimxrt1064-evk.repl index c15a32ae..81b1f8cd 100644 --- a/NXP/MIMXRT1064-EVK/renode/mimxrt1064-evk.repl +++ b/NXP/MIMXRT1064-EVK/renode/mimxrt1064-evk.repl @@ -24,6 +24,9 @@ user_button: Miscellaneous.Button @ gpio5 -> gpio5@0 // User LED D18 (Green, active low, connected to GPIO1 Pin 9) +gpio1: + 9 -> user_led@0 + user_led: Miscellaneous.LED @ gpio1 9 invert: true From bca799f95e6419bbb97a3798d8348a14997c9aee Mon Sep 17 00:00:00 2001 From: Ali Eissa Date: Sun, 13 Sep 2026 06:41:46 +0400 Subject: [PATCH 06/11] NXP i.MX RT1064-EVK: NetX Duo Virtual Ethernet Networking & Echo Demo Signed-off-by: Ali Eissa Assisted-by: Google DeepMind Antigravity --- NXP/MIMXRT1064-EVK/CMakeLists.txt | 164 +++++++-- NXP/MIMXRT1064-EVK/app/MIMXRT1062.h | 20 ++ NXP/MIMXRT1064-EVK/app/ansi_colors.h | 46 +++ NXP/MIMXRT1064-EVK/app/board_init.c | 5 +- NXP/MIMXRT1064-EVK/app/board_init.h | 2 +- NXP/MIMXRT1064-EVK/app/console.c | 2 +- NXP/MIMXRT1064-EVK/app/console.h | 2 +- .../app/demos/netx_echo/CMakeLists.txt | 108 ++++++ .../app/demos/netx_echo/client_main.c | 319 ++++++++++++++++++ NXP/MIMXRT1064-EVK/app/demos/netx_echo/main.c | 306 +++++++++++++++++ .../app/demos/netx_echo/nx_user.h | 21 ++ .../app/demos/netx_echo/test_echo.ps1 | 131 +++++++ .../app/demos/netx_echo/test_echo.sh | 97 ++++++ .../app/demos/threadx_basic/CMakeLists.txt | 55 +++ .../app/{ => demos/threadx_basic}/main.c | 0 NXP/MIMXRT1064-EVK/app/syscalls.c | 2 +- NXP/MIMXRT1064-EVK/app/sysmem.c | 2 +- NXP/MIMXRT1064-EVK/cmake/utilities.cmake | 4 +- NXP/MIMXRT1064-EVK/renode/mimxrt1064-evk.repl | 11 + NXP/MIMXRT1064-EVK/renode/mimxrt1064-evk.resc | 13 +- .../renode/mimxrt1064-network-multinode.resc | 51 +++ NXP/MIMXRT1064-EVK/scripts/build.ps1 | 53 +-- NXP/MIMXRT1064-EVK/scripts/build.sh | 45 ++- NXP/MIMXRT1064-EVK/scripts/fetch_sdk.ps1 | 50 ++- NXP/MIMXRT1064-EVK/scripts/fetch_sdk.sh | 36 +- NXP/MIMXRT1064-EVK/scripts/simulate.ps1 | 34 +- NXP/MIMXRT1064-EVK/scripts/simulate.sh | 25 +- 27 files changed, 1505 insertions(+), 99 deletions(-) create mode 100644 NXP/MIMXRT1064-EVK/app/MIMXRT1062.h create mode 100644 NXP/MIMXRT1064-EVK/app/ansi_colors.h create mode 100644 NXP/MIMXRT1064-EVK/app/demos/netx_echo/CMakeLists.txt create mode 100644 NXP/MIMXRT1064-EVK/app/demos/netx_echo/client_main.c create mode 100644 NXP/MIMXRT1064-EVK/app/demos/netx_echo/main.c create mode 100644 NXP/MIMXRT1064-EVK/app/demos/netx_echo/nx_user.h create mode 100644 NXP/MIMXRT1064-EVK/app/demos/netx_echo/test_echo.ps1 create mode 100644 NXP/MIMXRT1064-EVK/app/demos/netx_echo/test_echo.sh create mode 100644 NXP/MIMXRT1064-EVK/app/demos/threadx_basic/CMakeLists.txt rename NXP/MIMXRT1064-EVK/app/{ => demos/threadx_basic}/main.c (100%) create mode 100644 NXP/MIMXRT1064-EVK/renode/mimxrt1064-network-multinode.resc diff --git a/NXP/MIMXRT1064-EVK/CMakeLists.txt b/NXP/MIMXRT1064-EVK/CMakeLists.txt index 69036528..46546835 100644 --- a/NXP/MIMXRT1064-EVK/CMakeLists.txt +++ b/NXP/MIMXRT1064-EVK/CMakeLists.txt @@ -9,8 +9,9 @@ # Contributors: # Ali Eissa - 2026 version. -cmake_minimum_required(VERSION 3.5 FATAL_ERROR) +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) @@ -24,9 +25,11 @@ include(utilities) # Define the Project project(mimxrt1064_threadx C CXX ASM) -# Define ThreadX User Configurations -set(TX_USER_FILE "${CMAKE_CURRENT_LIST_DIR}/lib/threadx/tx_user.h" CACHE STRING "Enable TX user configuration") -set(TX_USER_FILE_DIR "${CMAKE_CURRENT_LIST_DIR}/lib/threadx") +# Ensure executable output (elf, bin, hex) goes directly to the top-level build directory +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}") + +# Select the active demo to build (default: netx_echo, or threadx_basic) +set(ACTIVE_DEMO "netx_echo" CACHE STRING "Active demo name to build: netx_echo, threadx_basic") # Set up paths for MCUXpresso SDK set(SDK_DIR "${CMAKE_CURRENT_LIST_DIR}/lib/mcux-sdk") @@ -34,6 +37,35 @@ 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 Auto-Detection +# Check if the active demo uses NetX Duo by looking for nx_user.h +if(EXISTS "${CMAKE_CURRENT_LIST_DIR}/app/demos/${ACTIVE_DEMO}/nx_user.h") + set(USE_NETXDUO ON) + 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(USE_NETXDUO OFF) +endif() + +# Check if the active demo has custom tx_user.h; otherwise fallback to lib/threadx/tx_user.h +if(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() + +# Compile ThreadX Kernel from root shared libs submodule +set(THREADX_DIR "${CMAKE_CURRENT_LIST_DIR}/../../libs/threadx") +add_subdirectory(${THREADX_DIR} threadx) + +if(USE_NETXDUO) + # Compile NetX Duo TCP/IP Stack from root shared libs submodule + set(NXD_ENABLE_FILE_SERVERS OFF CACHE BOOL "Disable FileX dependency in NetX Duo" FORCE) + set(NETXDUO_DIR "${CMAKE_CURRENT_LIST_DIR}/../../libs/netxduo") + add_subdirectory(${NETXDUO_DIR} netxduo) +endif() + # Compile the NXP MCUXpresso Driver & Board Library as an Object Library set(SDK_TARGET mcux_sdk) @@ -65,6 +97,7 @@ target_compile_definitions(${SDK_TARGET} FSL_SDK_DRIVER_QUICK_ACCESS_ENABLE=1 SDK_DEBUGCONSOLE=1 SKIP_SYSCLK_INIT=1 + __STARTUP_INITIALIZE_NONCACHEDATA=1 ) target_include_directories(${SDK_TARGET} @@ -79,26 +112,18 @@ target_include_directories(${SDK_TARGET} ${TX_USER_FILE_DIR} ) -# Compile ThreadX Kernel from root shared libs submodule -set(THREADX_DIR "${CMAKE_CURRENT_LIST_DIR}/../../libs/threadx") -add_subdirectory(${THREADX_DIR} threadx) - -# Create the Main Executable -set(EXE_TARGET mimxrt1064_threadx) - -add_executable(${EXE_TARGET} +# 1. Define Board BSP object library +add_library(board_bsp OBJECT app/startup/startup_mimxrt1064.S app/startup/tx_initialize_low_level.S app/board_init.c app/console.c - app/main.c app/sysmem.c app/syscalls.c ) -# Set compile definitions for our executable -target_compile_definitions(${EXE_TARGET} - PRIVATE +target_compile_definitions(board_bsp + PUBLIC CPU_MIMXRT1064DVL6A XIP_EXTERNAL_FLASH=1 XIP_BOOT_HEADER_ENABLE=1 @@ -106,11 +131,11 @@ target_compile_definitions(${EXE_TARGET} FSL_SDK_DRIVER_QUICK_ACCESS_ENABLE=1 SDK_DEBUGCONSOLE=1 SKIP_SYSCLK_INIT=1 + __STARTUP_INITIALIZE_NONCACHEDATA=1 ) -# Include paths -target_include_directories(${EXE_TARGET} - PRIVATE +target_include_directories(board_bsp + PUBLIC ${CMAKE_CURRENT_LIST_DIR}/app ${SDK_DIR}/CMSIS/Include ${SDK_DIR}/devices/MIMXRT1064 @@ -121,16 +146,99 @@ target_include_directories(${EXE_TARGET} ${TX_USER_FILE_DIR} ) -# Link libraries (includes ThreadX kernel and MCUXpresso SDK object libraries) -target_link_libraries(${EXE_TARGET} - PRIVATE - threadx +target_link_libraries(board_bsp + PUBLIC mcux_sdk + threadx ) -# Apply GCC linker script and print memory usage (utilities.cmake function) -set_target_linker(${EXE_TARGET} "${CMAKE_CURRENT_LIST_DIR}/app/startup/MIMXRT1064xxxxx_flexspi_nor.ld") - -# Post-build commands to generate raw .bin and .hex files -post_build(${EXE_TARGET}) +# 2. Define conditional NetX Duo driver library target +if(USE_NETXDUO) + add_library(netx_imxrt_driver OBJECT + ${SDK_DIR}/drivers/netx_driver/nx_driver_imxrt1062.c + ${SDK_DIR}/drivers/netx_driver/gnu/nx_driver_imxrt1062_low_level.S + ${SDK_DIR}/components/phy/fsl_phy.c + ${SDK_DIR}/drivers/fsl_enet.c + ) + + target_compile_definitions(netx_imxrt_driver + PUBLIC + 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(netx_imxrt_driver + PUBLIC + ${SDK_DIR}/drivers/netx_driver + ${SDK_DIR}/components/phy + ${CMAKE_CURRENT_LIST_DIR}/app + ${CMAKE_CURRENT_LIST_DIR}/app/demos/${ACTIVE_DEMO} + ${SDK_DIR}/CMSIS/Include + ${SDK_DIR}/devices/MIMXRT1064 + ${SDK_DIR}/drivers + ${SDK_DIR}/board + ${SDK_DIR}/utilities + ${SDK_DIR}/components/uart + ${TX_USER_FILE_DIR} + ) + + target_link_libraries(netx_imxrt_driver + PUBLIC + netxduo + threadx + mcux_sdk + ) + target_compile_options(netx_imxrt_driver PRIVATE -Wno-unused-variable) + + add_library(netx_imxrt_driver_client OBJECT + ${SDK_DIR}/drivers/netx_driver/nx_driver_imxrt1062.c + ${SDK_DIR}/drivers/netx_driver/gnu/nx_driver_imxrt1062_low_level.S + ${SDK_DIR}/components/phy/fsl_phy.c + ${SDK_DIR}/drivers/fsl_enet.c + ) + + target_compile_definitions(netx_imxrt_driver_client + PUBLIC + NETX_CLIENT_NODE=1 + 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(netx_imxrt_driver_client + PUBLIC + ${SDK_DIR}/drivers/netx_driver + ${SDK_DIR}/components/phy + ${CMAKE_CURRENT_LIST_DIR}/app + ${CMAKE_CURRENT_LIST_DIR}/app/demos/${ACTIVE_DEMO} + ${SDK_DIR}/CMSIS/Include + ${SDK_DIR}/devices/MIMXRT1064 + ${SDK_DIR}/drivers + ${SDK_DIR}/board + ${SDK_DIR}/utilities + ${SDK_DIR}/components/uart + ${TX_USER_FILE_DIR} + ) + + target_link_libraries(netx_imxrt_driver_client + PUBLIC + netxduo + threadx + mcux_sdk + ) + target_compile_options(netx_imxrt_driver_client PRIVATE -Wno-unused-variable) +endif() +# 3. Add the active demo subdirectory to build the executable target +add_subdirectory(app/demos/${ACTIVE_DEMO}) diff --git a/NXP/MIMXRT1064-EVK/app/MIMXRT1062.h b/NXP/MIMXRT1064-EVK/app/MIMXRT1062.h new file mode 100644 index 00000000..5c20680c --- /dev/null +++ b/NXP/MIMXRT1064-EVK/app/MIMXRT1062.h @@ -0,0 +1,20 @@ +/* + * Compatibility header: redirects MIMXRT1062.h from stock NetX Duo driver + * to MIMXRT1064 device registers without modifying vendor source files. + */ +#ifndef _MIMXRT1062_H_ +#define _MIMXRT1062_H_ + +#include "fsl_device_registers.h" + +/* + * Assign distinct MAC addresses to server and client nodes + * to prevent address collision on the Renode virtual switch. + */ +#if defined(NETX_CLIENT_NODE) +#define NX_DRIVER_ETHERNET_MAC {0x02, 0x11, 0x22, 0x33, 0x44, 0x53} +#else +#define NX_DRIVER_ETHERNET_MAC {0x02, 0x11, 0x22, 0x33, 0x44, 0x52} +#endif + +#endif /* _MIMXRT1062_H_ */ diff --git a/NXP/MIMXRT1064-EVK/app/ansi_colors.h b/NXP/MIMXRT1064-EVK/app/ansi_colors.h new file mode 100644 index 00000000..5b448d0c --- /dev/null +++ b/NXP/MIMXRT1064-EVK/app/ansi_colors.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2026 Eclipse ThreadX contributors + * + * 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. + */ + +#ifndef ANSI_COLORS_H +#define ANSI_COLORS_H + +/* ANSI Terminal Escape Codes for Colored Serial Output */ +#define ANSI_RESET "\x1b[0m" +#define ANSI_BOLD "\x1b[1m" + +/* Standard Primary Colors for Banners */ +#define ANSI_RED "\x1b[31m" +#define ANSI_GREEN "\x1b[32m" +#define ANSI_YELLOW "\x1b[33m" +#define ANSI_BLUE "\x1b[34m" +#define ANSI_MAGENTA "\x1b[35m" +#define ANSI_CYAN "\x1b[36m" +#define ANSI_WHITE "\x1b[37m" + +/* Subsystem Tags: Muted Slate Gray (256-color 243) */ +#define TAG_SYSTEM "\x1b[38;5;243m[System]" +#define TAG_HAL "\x1b[38;5;243m[HAL]" +#define TAG_NETWORK "\x1b[38;5;243m[NetX]" +#define TAG_NET_THREAD "\x1b[38;5;243m[Network Thread]" +#define TAG_ECHO "\x1b[38;5;243m[Echo]" +#define TAG_SERVER "\x1b[38;5;243m[Server]" +#define TAG_CLIENT "\x1b[38;5;243m[Client]" + +/* Message Colors: Soft, pastel feedback colors */ +#define MSG_INFO "\x1b[38;5;250m" /* Soft White/Gray for normal logs */ +#define MSG_SUCCESS "\x1b[38;5;114m" /* Soft Pastel Green for success */ +#define MSG_WARNING "\x1b[38;5;215m" /* Muted Gold/Orange for warnings */ +#define MSG_ERROR "\x1b[38;5;203m" /* Muted Coral/Red for failures */ +#define MSG_METRIC "\x1b[38;5;111m" /* Soft Sky Blue for data/measurements */ + +#endif /* ANSI_COLORS_H */ diff --git a/NXP/MIMXRT1064-EVK/app/board_init.c b/NXP/MIMXRT1064-EVK/app/board_init.c index 472a3c9b..0517fb0b 100644 --- a/NXP/MIMXRT1064-EVK/app/board_init.c +++ b/NXP/MIMXRT1064-EVK/app/board_init.c @@ -8,7 +8,7 @@ * SPDX-License-Identifier: MIT * * Contributors: - * Ali Eissa - 2026 NXP i.MX RT1064 port. + * Ali Eissa - 2026 version. */ #include "board_init.h" @@ -46,4 +46,7 @@ void board_init(void) /* 6. Initialize LPUART1 Serial Console at 115200 baud */ console_init(); + + /* 7. Configure Ethernet Pin Muxing (RMII and MDC/MDIO) */ + BOARD_InitENET(); } diff --git a/NXP/MIMXRT1064-EVK/app/board_init.h b/NXP/MIMXRT1064-EVK/app/board_init.h index 3080890b..c87f7a40 100644 --- a/NXP/MIMXRT1064-EVK/app/board_init.h +++ b/NXP/MIMXRT1064-EVK/app/board_init.h @@ -8,7 +8,7 @@ * SPDX-License-Identifier: MIT * * Contributors: - * Ali Eissa - 2026 NXP i.MX RT1064 port. + * Ali Eissa - 2026 version. */ #ifndef BOARD_INIT_H diff --git a/NXP/MIMXRT1064-EVK/app/console.c b/NXP/MIMXRT1064-EVK/app/console.c index 9c95756f..5befef29 100644 --- a/NXP/MIMXRT1064-EVK/app/console.c +++ b/NXP/MIMXRT1064-EVK/app/console.c @@ -8,7 +8,7 @@ * SPDX-License-Identifier: MIT * * Contributors: - * Ali Eissa - 2026 NXP i.MX RT1064 port. + * Ali Eissa - 2026 version. */ #include "console.h" diff --git a/NXP/MIMXRT1064-EVK/app/console.h b/NXP/MIMXRT1064-EVK/app/console.h index 89140a90..3907e183 100644 --- a/NXP/MIMXRT1064-EVK/app/console.h +++ b/NXP/MIMXRT1064-EVK/app/console.h @@ -8,7 +8,7 @@ * SPDX-License-Identifier: MIT * * Contributors: - * Ali Eissa - 2026 NXP i.MX RT1064 port. + * Ali Eissa - 2026 version. */ #ifndef CONSOLE_H diff --git a/NXP/MIMXRT1064-EVK/app/demos/netx_echo/CMakeLists.txt b/NXP/MIMXRT1064-EVK/app/demos/netx_echo/CMakeLists.txt new file mode 100644 index 00000000..a3a4ec5c --- /dev/null +++ b/NXP/MIMXRT1064-EVK/app/demos/netx_echo/CMakeLists.txt @@ -0,0 +1,108 @@ +# Copyright (c) 2026 Eclipse ThreadX contributors +# +# 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. + +# Server Executable Target (mimxrt1064_threadx) +add_executable(${PROJECT_NAME} + main.c +) + +# Set compile definitions for server +target_compile_definitions(${PROJECT_NAME} + PRIVATE + 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 +) + +# Include paths for server +target_include_directories(${PROJECT_NAME} + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/../.. + ${SDK_DIR}/drivers/netx_driver + ${SDK_DIR}/CMSIS/Include + ${SDK_DIR}/devices/MIMXRT1064 + ${SDK_DIR}/drivers + ${SDK_DIR}/board + ${SDK_DIR}/utilities + ${SDK_DIR}/components/uart + ${SDK_DIR}/components/phy + ${TX_USER_FILE_DIR} +) + +# Link libraries for server +target_link_libraries(${PROJECT_NAME} + PRIVATE + board_bsp + threadx + netxduo + netx_imxrt_driver + mcux_sdk +) + +# Apply GCC linker script and post-build outputs for server +set_target_linker(${PROJECT_NAME} "${CMAKE_CURRENT_SOURCE_DIR}/../../startup/MIMXRT1064xxxxx_flexspi_nor.ld") +post_build(${PROJECT_NAME}) + +# Automated Verification Client Executable Target (mimxrt1064_client) +set(CLIENT_TARGET "mimxrt1064_client") +add_executable(${CLIENT_TARGET} + client_main.c +) + +# Set compile definitions for client +target_compile_definitions(${CLIENT_TARGET} + PRIVATE + NETX_CLIENT_NODE=1 + 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 +) + +# Include paths for client +target_include_directories(${CLIENT_TARGET} + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/../.. + ${SDK_DIR}/drivers/netx_driver + ${SDK_DIR}/CMSIS/Include + ${SDK_DIR}/devices/MIMXRT1064 + ${SDK_DIR}/drivers + ${SDK_DIR}/board + ${SDK_DIR}/utilities + ${SDK_DIR}/components/uart + ${SDK_DIR}/components/phy + ${TX_USER_FILE_DIR} +) + +# Link libraries for client +target_link_libraries(${CLIENT_TARGET} + PRIVATE + board_bsp + threadx + netxduo + netx_imxrt_driver_client + mcux_sdk +) + +# Apply GCC linker script and post-build outputs for client +set_target_linker(${CLIENT_TARGET} "${CMAKE_CURRENT_SOURCE_DIR}/../../startup/MIMXRT1064xxxxx_flexspi_nor.ld") +post_build(${CLIENT_TARGET}) diff --git a/NXP/MIMXRT1064-EVK/app/demos/netx_echo/client_main.c b/NXP/MIMXRT1064-EVK/app/demos/netx_echo/client_main.c new file mode 100644 index 00000000..a9032e6e --- /dev/null +++ b/NXP/MIMXRT1064-EVK/app/demos/netx_echo/client_main.c @@ -0,0 +1,319 @@ +/* + * Copyright (c) 2026 Eclipse ThreadX contributors + * + * 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. + */ + +#include "board_init.h" +#include "console.h" +#include "tx_api.h" +#include "nx_api.h" +#include "ansi_colors.h" +#include +#include + +#define DEMO_STACK_SIZE 2048 +#define PACKET_SIZE 1536 +#define PACKET_POOL_SIZE (PACKET_SIZE * 24) +#define ECHO_SERVER_PORT 7 +#define ARP_CACHE_SIZE 1024 + +/* Static IP Configuration for Automated Verification Client */ +#define CLIENT_IP_ADDRESS IP_ADDRESS(192, 168, 0, 101) +#define SERVER_IP_ADDRESS IP_ADDRESS(192, 168, 0, 100) +#define NETWORK_MASK_VAL IP_ADDRESS(255, 255, 255, 0) +#define GATEWAY_ADDRESS_VAL IP_ADDRESS(192, 168, 0, 1) + +static TX_THREAD client_thread; +static uint8_t client_thread_stack[DEMO_STACK_SIZE]; + +static uint8_t ip_thread_stack[DEMO_STACK_SIZE]; +static uint8_t arp_cache_area[ARP_CACHE_SIZE]; + +static NX_PACKET_POOL client_pool; +static NX_IP client_ip; + +/* Place the NetX Duo packet pool in the NonCacheable section to ensure DMA coherency */ +__attribute__((section("NonCacheable"), aligned(64))) +static uint8_t packet_pool_area[PACKET_POOL_SIZE]; + +/* External hardware driver entry point for NXP i.MX RT ENET MAC */ +extern VOID nx_driver_imx(NX_IP_DRIVER *driver_req_ptr); + +static void client_thread_entry(ULONG thread_input); + +int main(void) +{ + /* Initialize MPU, system clocks (600 MHz), pins, LED GPIO, console, and ENET pins */ + board_init(); + + printf(ANSI_BOLD ANSI_CYAN "\r\n==================================================\r\n" ANSI_RESET); + printf(ANSI_BOLD ANSI_CYAN " Eclipse ThreadX & NetX Duo on NXP i.MX RT1064-EVK\r\n" ANSI_RESET); + printf(ANSI_BOLD ANSI_CYAN " Automated Network Verification Client (Renode)\r\n" ANSI_RESET); + printf(ANSI_BOLD ANSI_CYAN "==================================================\r\n\r\n" ANSI_RESET); + + printf(TAG_SYSTEM " " MSG_INFO "Core Clock: %lu MHz | Tick Rate: %u Hz\r\n" ANSI_RESET, + SystemCoreClock / 1000000UL, TX_TIMER_TICKS_PER_SECOND); + + /* Enter ThreadX kernel */ + tx_kernel_enter(); + + return 0; +} + +void tx_application_define(void *first_unused_memory) +{ + (void)first_unused_memory; + UINT status; + + printf(TAG_CLIENT " " MSG_INFO "Initializing NetX Duo System...\r\n" ANSI_RESET); + nx_system_initialize(); + + /* 1. Create packet pool in NonCacheable memory */ + status = nx_packet_pool_create(&client_pool, "Client Packet Pool", + PACKET_SIZE, packet_pool_area, PACKET_POOL_SIZE); + if (status != NX_SUCCESS) + { + printf(TAG_CLIENT " " MSG_ERROR "Failed to create packet pool: 0x%02X\r\n" ANSI_RESET, status); + return; + } + printf(TAG_CLIENT " " MSG_SUCCESS "Packet pool created (size: %u bytes in NonCacheable memory)\r\n" ANSI_RESET, + (unsigned int)sizeof(packet_pool_area)); + + /* 2. Create IP instance using the NXP i.MX RT ENET driver */ + status = nx_ip_create(&client_ip, "NetX Client IP", CLIENT_IP_ADDRESS, + NETWORK_MASK_VAL, &client_pool, nx_driver_imx, + ip_thread_stack, DEMO_STACK_SIZE, 1); + if (status != NX_SUCCESS) + { + printf(TAG_CLIENT " " MSG_ERROR "Failed to create IP instance: 0x%02X\r\n" ANSI_RESET, status); + return; + } + printf(TAG_CLIENT " " MSG_SUCCESS "IP instance created (192.168.0.101)\r\n" ANSI_RESET); + + /* 3. Set Gateway Address */ + nx_ip_gateway_address_set(&client_ip, GATEWAY_ADDRESS_VAL); + + /* 4. Enable ARP */ + printf(TAG_CLIENT " " MSG_INFO "Enabling ARP...\r\n" ANSI_RESET); + status = nx_arp_enable(&client_ip, (VOID *)arp_cache_area, ARP_CACHE_SIZE); + if (status != NX_SUCCESS) + { + printf(TAG_CLIENT " " MSG_ERROR "Failed to enable ARP: 0x%02X\r\n" ANSI_RESET, status); + } + + /* 5. Enable ICMP (Ping) */ + printf(TAG_CLIENT " " MSG_INFO "Enabling ICMP...\r\n" ANSI_RESET); + status = nx_icmp_enable(&client_ip); + if (status != NX_SUCCESS) + { + printf(TAG_CLIENT " " MSG_ERROR "Failed to enable ICMP: 0x%02X\r\n" ANSI_RESET, status); + } + + /* 6. Enable UDP */ + printf(TAG_CLIENT " " MSG_INFO "Enabling UDP...\r\n" ANSI_RESET); + status = nx_udp_enable(&client_ip); + if (status != NX_SUCCESS) + { + printf(TAG_CLIENT " " MSG_ERROR "Failed to enable UDP: 0x%02X\r\n" ANSI_RESET, status); + } + + /* 7. Enable TCP */ + printf(TAG_CLIENT " " MSG_INFO "Enabling TCP...\r\n" ANSI_RESET); + status = nx_tcp_enable(&client_ip); + if (status != NX_SUCCESS) + { + printf(TAG_CLIENT " " MSG_ERROR "Failed to enable TCP: 0x%02X\r\n" ANSI_RESET, status); + } + + /* 8. Start Automated Verification Thread */ + tx_thread_create(&client_thread, "Client Verification Thread", client_thread_entry, 0, + client_thread_stack, DEMO_STACK_SIZE, 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + printf(TAG_CLIENT " " MSG_SUCCESS "Verification thread registered.\r\n" ANSI_RESET); +} + +static void client_thread_entry(ULONG thread_input) +{ + (void)thread_input; + ULONG actual_status = 0; + UINT status; + int test_ping_passed = 0; + int test_udp_passed = 0; + int test_tcp_passed = 0; + + printf(TAG_CLIENT " " MSG_INFO "Bringing Ethernet Link UP...\r\n" ANSI_RESET); + status = nx_ip_driver_direct_command(&client_ip, NX_LINK_ENABLE, &actual_status); + if (status == NX_SUCCESS || status == NX_ALREADY_ENABLED) + { + printf(TAG_CLIENT " " MSG_SUCCESS "Ethernet link is UP!\r\n" ANSI_RESET); + } + else + { + printf(TAG_CLIENT " " MSG_WARNING "nx_ip_driver_direct_command NX_LINK_ENABLE status: 0x%02X\r\n" ANSI_RESET, status); + } + + /* Allow network stack and server node to settle */ + printf(TAG_CLIENT " " MSG_INFO "Waiting for network convergence...\r\n" ANSI_RESET); + tx_thread_sleep(150); + + printf("\r\n" ANSI_BOLD ANSI_CYAN "==================================================\r\n" ANSI_RESET); + printf(ANSI_BOLD ANSI_CYAN " Starting Multi-Node Network Verification Suite\r\n" ANSI_RESET); + printf(ANSI_CYAN " Target Echo Server: 192.168.0.100 (Port 7)\r\n" ANSI_RESET); + printf(ANSI_CYAN " Local Client Node: 192.168.0.101\r\n" ANSI_RESET); + printf(ANSI_BOLD ANSI_CYAN "==================================================\r\n\r\n" ANSI_RESET); + + /* ------------------------------------------------------------------ + * Test 1: ICMP Ping (Echo Request & Reply) + * ------------------------------------------------------------------ */ + printf(TAG_CLIENT " [Test 1/3] Testing ICMP Ping to 192.168.0.100...\r\n"); + NX_PACKET *ping_response = NX_NULL; + status = nx_icmp_ping(&client_ip, SERVER_IP_ADDRESS, "ThreadX_Ping", 12, &ping_response, 200); + if (status == NX_SUCCESS && ping_response != NX_NULL) + { + printf(TAG_CLIENT " " MSG_SUCCESS "[PASS] ICMP Ping successful! Response received from 192.168.0.100\r\n" ANSI_RESET); + nx_packet_release(ping_response); + test_ping_passed = 1; + } + else + { + printf(TAG_CLIENT " " MSG_ERROR "[FAIL] ICMP Ping timed out or failed: status 0x%02X\r\n" ANSI_RESET, status); + } + + /* Small delay between tests */ + tx_thread_sleep(50); + + /* ------------------------------------------------------------------ + * Test 2: UDP Echo (Datagram Tx & Rx on Port 7) + * ------------------------------------------------------------------ */ + printf("\r\n" TAG_CLIENT " [Test 2/3] Testing UDP Echo on port 7...\r\n"); + NX_UDP_SOCKET udp_client_socket; + status = nx_udp_socket_create(&client_ip, &udp_client_socket, "Client UDP Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + if (status == NX_SUCCESS) + { + status = nx_udp_socket_bind(&udp_client_socket, NX_ANY_PORT, TX_WAIT_FOREVER); + if (status == NX_SUCCESS) + { + NX_PACKET *tx_packet = NX_NULL; + if (nx_packet_allocate(&client_pool, &tx_packet, NX_UDP_PACKET, TX_WAIT_FOREVER) == NX_SUCCESS) + { + const char *udp_payload = "Hello ThreadX UDP Echo!"; + nx_packet_data_append(tx_packet, (VOID *)udp_payload, strlen(udp_payload), &client_pool, TX_WAIT_FOREVER); + printf(TAG_CLIENT " " MSG_INFO "Sent UDP payload: '%s'\r\n" ANSI_RESET, udp_payload); + nx_udp_socket_send(&udp_client_socket, tx_packet, SERVER_IP_ADDRESS, ECHO_SERVER_PORT); + + NX_PACKET *rx_packet = NX_NULL; + status = nx_udp_socket_receive(&udp_client_socket, &rx_packet, 200); + if (status == NX_SUCCESS && rx_packet != NX_NULL) + { + printf(TAG_CLIENT " " MSG_SUCCESS "[PASS] Received UDP Echo: '%.*s' (%lu bytes)\r\n" ANSI_RESET, + (int)rx_packet->nx_packet_length, rx_packet->nx_packet_prepend_ptr, rx_packet->nx_packet_length); + nx_packet_release(rx_packet); + test_udp_passed = 1; + } + else + { + printf(TAG_CLIENT " " MSG_ERROR "[FAIL] UDP Echo receive timed out or failed: 0x%02X\r\n" ANSI_RESET, status); + } + } + nx_udp_socket_unbind(&udp_client_socket); + } + nx_udp_socket_delete(&udp_client_socket); + } + else + { + printf(TAG_CLIENT " " MSG_ERROR "[FAIL] Failed to create UDP socket: 0x%02X\r\n" ANSI_RESET, status); + } + + /* Small delay between tests */ + tx_thread_sleep(50); + + /* ------------------------------------------------------------------ + * Test 3: TCP Echo (Connection, Stream Tx & Rx on Port 7) + * ------------------------------------------------------------------ */ + printf("\r\n" TAG_CLIENT " [Test 3/3] Testing TCP Echo on port 7...\r\n"); + NX_TCP_SOCKET tcp_client_socket; + status = nx_tcp_socket_create(&client_ip, &tcp_client_socket, "Client TCP Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 512, NX_NULL, NX_NULL); + if (status == NX_SUCCESS) + { + status = nx_tcp_client_socket_bind(&tcp_client_socket, NX_ANY_PORT, TX_WAIT_FOREVER); + if (status == NX_SUCCESS) + { + printf(TAG_CLIENT " " MSG_INFO "Connecting to 192.168.0.100:7...\r\n" ANSI_RESET); + status = nx_tcp_client_socket_connect(&tcp_client_socket, SERVER_IP_ADDRESS, ECHO_SERVER_PORT, 200); + if (status == NX_SUCCESS) + { + printf(TAG_CLIENT " " MSG_SUCCESS "TCP Connected! Sending stream payload...\r\n" ANSI_RESET); + NX_PACKET *tx_packet = NX_NULL; + if (nx_packet_allocate(&client_pool, &tx_packet, NX_TCP_PACKET, TX_WAIT_FOREVER) == NX_SUCCESS) + { + const char *tcp_payload = "Hello ThreadX TCP Echo!"; + nx_packet_data_append(tx_packet, (VOID *)tcp_payload, strlen(tcp_payload), &client_pool, TX_WAIT_FOREVER); + printf(TAG_CLIENT " " MSG_INFO "Sent TCP payload: '%s'\r\n" ANSI_RESET, tcp_payload); + nx_tcp_socket_send(&tcp_client_socket, tx_packet, 200); + + NX_PACKET *rx_packet = NX_NULL; + status = nx_tcp_socket_receive(&tcp_client_socket, &rx_packet, 200); + if (status == NX_SUCCESS && rx_packet != NX_NULL) + { + printf(TAG_CLIENT " " MSG_SUCCESS "[PASS] Received TCP Echo: '%.*s' (%lu bytes)\r\n" ANSI_RESET, + (int)rx_packet->nx_packet_length, rx_packet->nx_packet_prepend_ptr, rx_packet->nx_packet_length); + nx_packet_release(rx_packet); + test_tcp_passed = 1; + } + else + { + printf(TAG_CLIENT " " MSG_ERROR "[FAIL] TCP Echo receive timed out or failed: 0x%02X\r\n" ANSI_RESET, status); + } + } + nx_tcp_socket_disconnect(&tcp_client_socket, 100); + } + else + { + printf(TAG_CLIENT " " MSG_ERROR "[FAIL] TCP connect to 192.168.0.100:7 failed: 0x%02X\r\n" ANSI_RESET, status); + } + nx_tcp_client_socket_unbind(&tcp_client_socket); + } + nx_tcp_socket_delete(&tcp_client_socket); + } + else + { + printf(TAG_CLIENT " " MSG_ERROR "[FAIL] Failed to create TCP socket: 0x%02X\r\n" ANSI_RESET, status); + } + + /* ------------------------------------------------------------------ + * Verification Summary + * ------------------------------------------------------------------ */ + printf("\r\n" ANSI_BOLD "==================================================\r\n" ANSI_RESET); + if (test_ping_passed && test_udp_passed && test_tcp_passed) + { + printf(ANSI_BOLD ANSI_GREEN " [VERIFICATION SUCCESS] ALL NETWORK TESTS PASSED!\r\n" ANSI_RESET); + printf(ANSI_GREEN " - [PASS] ICMP Ping (Echo Request & Reply)\r\n" ANSI_RESET); + printf(ANSI_GREEN " - [PASS] UDP Echo (Datagram Tx & Rx)\r\n" ANSI_RESET); + printf(ANSI_GREEN " - [PASS] TCP Echo (Connection, Stream Tx & Rx)\r\n" ANSI_RESET); + } + else + { + printf(ANSI_BOLD ANSI_RED " [VERIFICATION INCOMPLETE] SOME TESTS FAILED!\r\n" ANSI_RESET); + if (!test_ping_passed) printf(ANSI_RED " - [FAIL] ICMP Ping\r\n" ANSI_RESET); + if (!test_udp_passed) printf(ANSI_RED " - [FAIL] UDP Echo\r\n" ANSI_RESET); + if (!test_tcp_passed) printf(ANSI_RED " - [FAIL] TCP Echo\r\n" ANSI_RESET); + } + printf(ANSI_BOLD "==================================================\r\n\r\n" ANSI_RESET); + + /* Heartbeat loop */ + while (1) + { + tx_thread_sleep(50); + USER_LED_TOGGLE(); + } +} diff --git a/NXP/MIMXRT1064-EVK/app/demos/netx_echo/main.c b/NXP/MIMXRT1064-EVK/app/demos/netx_echo/main.c new file mode 100644 index 00000000..0e9fff45 --- /dev/null +++ b/NXP/MIMXRT1064-EVK/app/demos/netx_echo/main.c @@ -0,0 +1,306 @@ +/* + * Copyright (c) 2026 Eclipse ThreadX contributors + * + * 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. + */ + +#include "board_init.h" +#include "console.h" +#include "tx_api.h" +#include "nx_api.h" +#include "ansi_colors.h" +#include + +#define DEMO_STACK_SIZE 2048 +#define PACKET_SIZE 1536 +#define PACKET_POOL_SIZE (PACKET_SIZE * 24) +#define ECHO_SERVER_PORT 7 +#define ARP_CACHE_SIZE 1024 + +/* Static IP Configuration for Renode Simulation & Physical Testing */ +#define IP_ADDRESS_VAL IP_ADDRESS(192, 168, 0, 100) +#define NETWORK_MASK_VAL IP_ADDRESS(255, 255, 255, 0) +#define GATEWAY_ADDRESS_VAL IP_ADDRESS(192, 168, 0, 1) + +static TX_THREAD monitor_thread; +static uint8_t monitor_thread_stack[DEMO_STACK_SIZE]; + +static TX_THREAD udp_echo_thread; +static uint8_t udp_echo_thread_stack[DEMO_STACK_SIZE]; + +static TX_THREAD tcp_echo_thread; +static uint8_t tcp_echo_thread_stack[DEMO_STACK_SIZE]; + +static uint8_t ip_thread_stack[DEMO_STACK_SIZE]; +static uint8_t arp_cache_area[ARP_CACHE_SIZE]; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Place the NetX Duo packet pool in the NonCacheable section to ensure DMA coherency */ +__attribute__((section("NonCacheable"), aligned(64))) +static uint8_t packet_pool_area[PACKET_POOL_SIZE]; + +/* External hardware driver entry point for NXP i.MX RT ENET MAC */ +extern VOID nx_driver_imx(NX_IP_DRIVER *driver_req_ptr); + +static void monitor_thread_entry(ULONG thread_input); +static void udp_echo_thread_entry(ULONG thread_input); +static void tcp_echo_thread_entry(ULONG thread_input); + +int main(void) +{ + /* Initialize MPU, system clocks (600 MHz), pins, LED GPIO, console, and ENET pins */ + board_init(); + + printf(ANSI_BOLD ANSI_CYAN "\r\n==================================================\r\n" ANSI_RESET); + printf(ANSI_BOLD ANSI_CYAN " Eclipse ThreadX & NetX Duo on NXP i.MX RT1064-EVK\r\n" ANSI_RESET); + printf(ANSI_BOLD ANSI_CYAN " Virtual Ethernet Networking & Echo Demo (Renode)\r\n" ANSI_RESET); + printf(ANSI_BOLD ANSI_CYAN "==================================================\r\n\r\n" ANSI_RESET); + + printf(TAG_SYSTEM " " MSG_INFO "Core Clock: %lu MHz | Tick Rate: %u Hz\r\n" ANSI_RESET, + SystemCoreClock / 1000000UL, TX_TIMER_TICKS_PER_SECOND); + + /* Enter ThreadX kernel */ + tx_kernel_enter(); + + return 0; +} + +void tx_application_define(void *first_unused_memory) +{ + (void)first_unused_memory; + UINT status; + + printf(TAG_NETWORK " " MSG_INFO "Initializing NetX Duo System...\r\n" ANSI_RESET); + nx_system_initialize(); + + /* 1. Create packet pool in NonCacheable memory */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", + PACKET_SIZE, packet_pool_area, PACKET_POOL_SIZE); + if (status != NX_SUCCESS) + { + printf(TAG_NETWORK " " MSG_ERROR "Failed to create packet pool: 0x%02X\r\n" ANSI_RESET, status); + return; + } + printf(TAG_NETWORK " " MSG_SUCCESS "Packet pool created (size: %u bytes in NonCacheable memory)\r\n" ANSI_RESET, + (unsigned int)sizeof(packet_pool_area)); + + /* 2. Create IP instance using the NXP i.MX RT ENET driver */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS_VAL, + NETWORK_MASK_VAL, &pool_0, nx_driver_imx, + ip_thread_stack, DEMO_STACK_SIZE, 1); + if (status != NX_SUCCESS) + { + printf(TAG_NETWORK " " MSG_ERROR "Failed to create IP instance: 0x%02X\r\n" ANSI_RESET, status); + return; + } + printf(TAG_NETWORK " " MSG_SUCCESS "IP instance created\r\n" ANSI_RESET); + + /* 3. Set Gateway Address */ + nx_ip_gateway_address_set(&ip_0, GATEWAY_ADDRESS_VAL); + + /* 4. Enable ARP */ + printf(TAG_NETWORK " " MSG_INFO "Enabling ARP...\r\n" ANSI_RESET); + status = nx_arp_enable(&ip_0, (VOID *)arp_cache_area, ARP_CACHE_SIZE); + if (status != NX_SUCCESS) + { + printf(TAG_NETWORK " " MSG_ERROR "Failed to enable ARP: 0x%02X\r\n" ANSI_RESET, status); + } + + /* 5. Enable ICMP (Ping) */ + printf(TAG_NETWORK " " MSG_INFO "Enabling ICMP (Ping responder)...\r\n" ANSI_RESET); + status = nx_icmp_enable(&ip_0); + if (status != NX_SUCCESS) + { + printf(TAG_NETWORK " " MSG_ERROR "Failed to enable ICMP: 0x%02X\r\n" ANSI_RESET, status); + } + + /* 6. Enable UDP */ + printf(TAG_NETWORK " " MSG_INFO "Enabling UDP...\r\n" ANSI_RESET); + status = nx_udp_enable(&ip_0); + if (status != NX_SUCCESS) + { + printf(TAG_NETWORK " " MSG_ERROR "Failed to enable UDP: 0x%02X\r\n" ANSI_RESET, status); + } + + /* 7. Enable TCP */ + printf(TAG_NETWORK " " MSG_INFO "Enabling TCP...\r\n" ANSI_RESET); + status = nx_tcp_enable(&ip_0); + if (status != NX_SUCCESS) + { + printf(TAG_NETWORK " " MSG_ERROR "Failed to enable TCP: 0x%02X\r\n" ANSI_RESET, status); + } + + /* 8. Start Monitor / Heartbeat Thread */ + tx_thread_create(&monitor_thread, "Network Monitor", monitor_thread_entry, 0, + monitor_thread_stack, DEMO_STACK_SIZE, 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + /* 9. Start UDP Echo Server Thread */ + tx_thread_create(&udp_echo_thread, "UDP Echo Thread", udp_echo_thread_entry, 0, + udp_echo_thread_stack, DEMO_STACK_SIZE, 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + /* 10. Start TCP Echo Server Thread */ + tx_thread_create(&tcp_echo_thread, "TCP Echo Thread", tcp_echo_thread_entry, 0, + tcp_echo_thread_stack, DEMO_STACK_SIZE, 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + printf(TAG_NETWORK " " MSG_SUCCESS "All network threads registered successfully.\r\n" ANSI_RESET); +} + +static void monitor_thread_entry(ULONG thread_input) +{ + (void)thread_input; + ULONG ip_address = 0; + ULONG network_mask = 0; + ULONG actual_status = 0; + uint8_t led_state = 0; + + printf(TAG_NETWORK " " MSG_INFO "Bringing Ethernet Link UP...\r\n" ANSI_RESET); + UINT status = nx_ip_driver_direct_command(&ip_0, NX_LINK_ENABLE, &actual_status); + if (status == NX_SUCCESS || status == NX_ALREADY_ENABLED) + { + printf(TAG_NETWORK " " MSG_SUCCESS "Ethernet link is UP!\r\n" ANSI_RESET); + } + else + { + printf(TAG_NETWORK " " MSG_WARNING "nx_ip_driver_direct_command NX_LINK_ENABLE status: 0x%02X\r\n" ANSI_RESET, status); + } + + nx_ip_address_get(&ip_0, &ip_address, &network_mask); + printf("\r\n" ANSI_BOLD ANSI_GREEN "================ Network Ready ================\r\n" ANSI_RESET); + printf(ANSI_GREEN " Static IPv4 : %lu.%lu.%lu.%lu\r\n" ANSI_RESET, + (ip_address >> 24) & 0xFF, (ip_address >> 16) & 0xFF, + (ip_address >> 8) & 0xFF, ip_address & 0xFF); + printf(ANSI_GREEN " Subnet Mask : %lu.%lu.%lu.%lu\r\n" ANSI_RESET, + (network_mask >> 24) & 0xFF, (network_mask >> 16) & 0xFF, + (network_mask >> 8) & 0xFF, network_mask & 0xFF); + printf(ANSI_GREEN " Services : ICMP Ping, UDP Echo (Port 7), TCP Echo (Port 7)\r\n" ANSI_RESET); + printf(ANSI_BOLD ANSI_GREEN "===============================================\r\n\r\n" ANSI_RESET); + + while (1) + { + /* Sleep 500 ms (50 ticks) */ + tx_thread_sleep(50); + + /* Toggle User LED to indicate active heartbeat */ + USER_LED_TOGGLE(); + led_state = !led_state; + } +} + +static void udp_echo_thread_entry(ULONG thread_input) +{ + NX_UDP_SOCKET udp_socket; + NX_PACKET *rx_packet; + UINT status; + + (void)thread_input; + + status = nx_udp_socket_create(&ip_0, &udp_socket, "UDP Echo Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + if (status != NX_SUCCESS) + { + printf(TAG_ECHO " " MSG_ERROR "Failed to create UDP socket: 0x%02X\r\n" ANSI_RESET, status); + return; + } + + status = nx_udp_socket_bind(&udp_socket, ECHO_SERVER_PORT, TX_WAIT_FOREVER); + if (status != NX_SUCCESS) + { + printf(TAG_ECHO " " MSG_ERROR "Failed to bind UDP port %u: 0x%02X\r\n" ANSI_RESET, ECHO_SERVER_PORT, status); + nx_udp_socket_delete(&udp_socket); + return; + } + + printf(TAG_ECHO " " MSG_INFO "UDP Echo Server listening on port %d\r\n" ANSI_RESET, ECHO_SERVER_PORT); + + while (1) + { + status = nx_udp_socket_receive(&udp_socket, &rx_packet, TX_WAIT_FOREVER); + if (status == NX_SUCCESS) + { + ULONG peer_ip = 0; + UINT peer_port = 0; + nx_udp_source_extract(rx_packet, &peer_ip, &peer_port); + + printf(TAG_ECHO " " MSG_SUCCESS "UDP Rx from %lu.%lu.%lu.%lu:%u (%lu bytes), echoing...\r\n" ANSI_RESET, + (peer_ip >> 24) & 0xFF, (peer_ip >> 16) & 0xFF, + (peer_ip >> 8) & 0xFF, peer_ip & 0xFF, + peer_port, rx_packet->nx_packet_length); + + /* Allocate a response packet from the pool */ + NX_PACKET *tx_packet = NX_NULL; + if (nx_packet_allocate(&pool_0, &tx_packet, NX_UDP_PACKET, TX_NO_WAIT) == NX_SUCCESS) + { + nx_packet_data_append(tx_packet, rx_packet->nx_packet_prepend_ptr, + rx_packet->nx_packet_length, &pool_0, TX_NO_WAIT); + nx_udp_socket_send(&udp_socket, tx_packet, peer_ip, peer_port); + } + + /* Release the received packet */ + nx_packet_release(rx_packet); + } + } +} + +static void tcp_echo_thread_entry(ULONG thread_input) +{ + NX_TCP_SOCKET echo_socket; + NX_PACKET *packet_ptr; + UINT status; + + (void)thread_input; + + status = nx_tcp_socket_create(&ip_0, &echo_socket, "TCP Echo Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, + 512, NX_NULL, NX_NULL); + if (status != NX_SUCCESS) + { + printf(TAG_ECHO " " MSG_ERROR "Failed to create TCP socket: 0x%02X\r\n" ANSI_RESET, status); + return; + } + + printf(TAG_ECHO " " MSG_INFO "TCP Echo Server listening on port %d\r\n" ANSI_RESET, ECHO_SERVER_PORT); + + while (1) + { + status = nx_tcp_server_socket_listen(&ip_0, ECHO_SERVER_PORT, &echo_socket, 5, NX_NULL); + if (status != NX_SUCCESS) + { + nx_tcp_server_socket_unlisten(&ip_0, ECHO_SERVER_PORT); + tx_thread_sleep(10); + continue; + } + + if (nx_tcp_server_socket_accept(&echo_socket, NX_WAIT_FOREVER) == NX_SUCCESS) + { + printf(TAG_ECHO " " MSG_SUCCESS "TCP Client connected.\r\n" ANSI_RESET); + + while (nx_tcp_socket_receive(&echo_socket, &packet_ptr, NX_WAIT_FOREVER) == NX_SUCCESS) + { + printf(TAG_ECHO " " MSG_SUCCESS "TCP Rx %lu bytes, echoing...\r\n" ANSI_RESET, + packet_ptr->nx_packet_length); + NX_PACKET *tx_packet = NX_NULL; + if (nx_packet_allocate(&pool_0, &tx_packet, NX_TCP_PACKET, TX_WAIT_FOREVER) == NX_SUCCESS) + { + nx_packet_data_append(tx_packet, packet_ptr->nx_packet_prepend_ptr, + packet_ptr->nx_packet_length, &pool_0, TX_WAIT_FOREVER); + nx_tcp_socket_send(&echo_socket, tx_packet, NX_WAIT_FOREVER); + } + nx_packet_release(packet_ptr); + } + + printf(TAG_ECHO " " MSG_WARNING "TCP Client disconnected.\r\n" ANSI_RESET); + nx_tcp_socket_disconnect(&echo_socket, NX_WAIT_FOREVER); + nx_tcp_server_socket_unaccept(&echo_socket); + } + nx_tcp_server_socket_unlisten(&ip_0, ECHO_SERVER_PORT); + } +} diff --git a/NXP/MIMXRT1064-EVK/app/demos/netx_echo/nx_user.h b/NXP/MIMXRT1064-EVK/app/demos/netx_echo/nx_user.h new file mode 100644 index 00000000..eccf436a --- /dev/null +++ b/NXP/MIMXRT1064-EVK/app/demos/netx_echo/nx_user.h @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2026 Eclipse ThreadX contributors + * + * 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. + */ + +#ifndef NX_USER_H +#define NX_USER_H + +#define NX_DISABLE_IPV6 +#define NX_PHYSICAL_HEADER 16 +#define NX_ENABLE_EXTENDED_NOTIFY_SUPPORT + +#endif /* NX_USER_H */ diff --git a/NXP/MIMXRT1064-EVK/app/demos/netx_echo/test_echo.ps1 b/NXP/MIMXRT1064-EVK/app/demos/netx_echo/test_echo.ps1 new file mode 100644 index 00000000..cf1e5d0a --- /dev/null +++ b/NXP/MIMXRT1064-EVK/app/demos/netx_echo/test_echo.ps1 @@ -0,0 +1,131 @@ +# Copyright (c) 2026 Eclipse ThreadX contributors +# +# 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. + +param ( + [string]$IP = "192.168.0.100", + [int]$Port = 7 +) + +Write-Host "==========================================" -ForegroundColor Cyan +Write-Host " NetX Duo Virtual Networking Verification" -ForegroundColor Cyan +Write-Host " Target Device: $IP (Port: $Port)" -ForegroundColor Cyan +Write-Host "==========================================" -ForegroundColor Cyan +Write-Host "" + +$AllPassed = $true + +# ---------------------------------------------------- +# Test 1: ICMP Ping +# ---------------------------------------------------- +Write-Host "[Test 1/3] Testing ICMP Ping (Echo Request)..." -ForegroundColor Yellow +$PingSuccess = $false +try { + $pingRes = Test-Connection -ComputerName $IP -Count 2 -Quiet -ErrorAction Stop + if ($pingRes) { + $PingSuccess = $true + } +} catch { + # Fallback to ping.exe + $res = ping -n 2 -w 1000 $IP + if ($LASTEXITCODE -eq 0) { + $PingSuccess = $true + } +} + +if ($PingSuccess) { + Write-Host "[PASS] ICMP Ping responded successfully from $IP" -ForegroundColor Green +} else { + Write-Host "[FAIL] ICMP Ping timed out or failed to reach $IP" -ForegroundColor Red + $AllPassed = $false +} +Write-Host "" + +# ---------------------------------------------------- +# Test 2: UDP Echo +# ---------------------------------------------------- +Write-Host "[Test 2/3] Testing UDP Echo on port $Port..." -ForegroundColor Yellow +$UdpClient = New-Object System.Net.Sockets.UdpClient +$UdpClient.Client.ReceiveTimeout = 3000 + +$UdpMsg = "Hello ThreadX UDP Echo!" +$UdpBytes = [System.Text.Encoding]::ASCII.GetBytes($UdpMsg) + +try { + $UdpClient.Connect($IP, $Port) + [void]$UdpClient.Send($UdpBytes, $UdpBytes.Length) + Write-Host "Sent UDP: '$UdpMsg'" + + $RemoteEndpoint = New-Object System.Net.IPEndPoint([System.Net.IPAddress]::Any, 0) + $ReceivedBytes = $UdpClient.Receive([ref]$RemoteEndpoint) + $ReceivedMsg = [System.Text.Encoding]::ASCII.GetString($ReceivedBytes) + Write-Host "Received UDP: '$ReceivedMsg'" + + if ($ReceivedMsg -eq $UdpMsg) { + Write-Host "[PASS] UDP Echo verified successfully!" -ForegroundColor Green + } else { + Write-Host "[FAIL] UDP payload mismatch: expected '$UdpMsg', got '$ReceivedMsg'" -ForegroundColor Red + $AllPassed = $false + } +} catch { + Write-Host "[FAIL] UDP Echo failed: $_" -ForegroundColor Red + $AllPassed = $false +} finally { + $UdpClient.Close() +} +Write-Host "" + +# ---------------------------------------------------- +# Test 3: TCP Echo +# ---------------------------------------------------- +Write-Host "[Test 3/3] Testing TCP Echo on port $Port..." -ForegroundColor Yellow +$TcpClient = $null +try { + $TcpClient = New-Object System.Net.Sockets.TcpClient + $TcpClient.ReceiveTimeout = 3000 + $TcpClient.SendTimeout = 3000 + $TcpClient.Connect($IP, $Port) + + $Stream = $TcpClient.GetStream() + $Writer = New-Object System.IO.StreamWriter($Stream) + $Reader = New-Object System.IO.StreamReader($Stream) + + $TcpMsg = "Hello ThreadX TCP Echo!" + Write-Host "Sent TCP: '$TcpMsg'" + $Writer.WriteLine($TcpMsg) + $Writer.Flush() + + $TcpResponse = $Reader.ReadLine() + Write-Host "Received TCP: '$TcpResponse'" + + if ($TcpResponse -eq $TcpMsg) { + Write-Host "[PASS] TCP Echo verified successfully!" -ForegroundColor Green + } else { + Write-Host "[FAIL] TCP payload mismatch: expected '$TcpMsg', got '$TcpResponse'" -ForegroundColor Red + $AllPassed = $false + } +} catch { + Write-Host "[FAIL] TCP Echo failed: $_" -ForegroundColor Red + $AllPassed = $false +} finally { + if ($TcpClient) { $TcpClient.Close() } +} +Write-Host "" + +# ---------------------------------------------------- +# Summary +# ---------------------------------------------------- +Write-Host "==========================================" -ForegroundColor Cyan +if ($AllPassed) { + Write-Host " ALL TESTS PASSED! NetX Duo is fully verified." -ForegroundColor Green +} else { + Write-Host " SOME TESTS FAILED. Verify Renode TAP and network connection." -ForegroundColor Red +} +Write-Host "==========================================" -ForegroundColor Cyan diff --git a/NXP/MIMXRT1064-EVK/app/demos/netx_echo/test_echo.sh b/NXP/MIMXRT1064-EVK/app/demos/netx_echo/test_echo.sh new file mode 100644 index 00000000..ec316cec --- /dev/null +++ b/NXP/MIMXRT1064-EVK/app/demos/netx_echo/test_echo.sh @@ -0,0 +1,97 @@ +#!/usr/bin/env bash +# Copyright (c) 2026 Eclipse ThreadX contributors +# +# 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. + +set -e + +IP=${1:-"192.168.0.100"} +PORT=7 + +echo "==========================================" +echo " NetX Duo Virtual Networking Verification" +echo " Target Device: ${IP} (Port: ${PORT})" +echo "==========================================" +echo "" + +ALL_PASSED=1 + +# 1. ICMP Ping Test +echo "[Test 1/3] Testing ICMP Ping (Echo Request)..." +if ping -c 2 -W 2 "${IP}" > /dev/null 2>&1; then + echo "[PASS] ICMP Ping responded successfully from ${IP}" +else + echo "[FAIL] ICMP Ping timed out or failed to reach ${IP}" + ALL_PASSED=0 +fi +echo "" + +# 2. UDP Echo Test +echo "[Test 2/3] Testing UDP Echo on port ${PORT}..." +UDP_MSG="Hello ThreadX UDP Echo!" +UDP_RES=$(python3 -c " +import socket, sys +try: + s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + s.settimeout(3.0) + s.sendto(b'${UDP_MSG}', ('${IP}', ${PORT})) + data, _ = s.recvfrom(1024) + print(data.decode('ascii', errors='ignore')) +except Exception as e: + sys.exit(1) +finally: + s.close() +" 2>/dev/null || true) + +if [ "${UDP_RES}" = "${UDP_MSG}" ]; then + echo "Sent UDP: '${UDP_MSG}'" + echo "Received UDP: '${UDP_RES}'" + echo "[PASS] UDP Echo verified successfully!" +else + echo "[FAIL] UDP Echo failed (got '${UDP_RES}')" + ALL_PASSED=0 +fi +echo "" + +# 3. TCP Echo Test +echo "[Test 3/3] Testing TCP Echo on port ${PORT}..." +TCP_MSG="Hello ThreadX TCP Echo!" +TCP_RES=$(python3 -c " +import socket, sys +try: + s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + s.settimeout(3.0) + s.connect(('${IP}', ${PORT})) + s.sendall(b'${TCP_MSG}\n') + data = s.recv(1024) + print(data.decode('ascii', errors='ignore').strip()) +except Exception as e: + sys.exit(1) +finally: + s.close() +" 2>/dev/null || true) + +if [ "${TCP_RES}" = "${TCP_MSG}" ]; then + echo "Sent TCP: '${TCP_MSG}'" + echo "Received TCP: '${TCP_RES}'" + echo "[PASS] TCP Echo verified successfully!" +else + echo "[FAIL] TCP Echo failed (got '${TCP_RES}')" + ALL_PASSED=0 +fi +echo "" + +echo "==========================================" +if [ "${ALL_PASSED}" -eq 1 ]; then + echo " ALL TESTS PASSED! NetX Duo is fully verified." +else + echo " SOME TESTS FAILED. Verify Renode TAP and network connection." +fi +echo "==========================================" diff --git a/NXP/MIMXRT1064-EVK/app/demos/threadx_basic/CMakeLists.txt b/NXP/MIMXRT1064-EVK/app/demos/threadx_basic/CMakeLists.txt new file mode 100644 index 00000000..41f8f3bb --- /dev/null +++ b/NXP/MIMXRT1064-EVK/app/demos/threadx_basic/CMakeLists.txt @@ -0,0 +1,55 @@ +# Copyright (c) 2026 Eclipse ThreadX contributors +# +# 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. + +add_executable(${PROJECT_NAME} + main.c +) + +# Set compile definitions for our executable +target_compile_definitions(${PROJECT_NAME} + PRIVATE + 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 +) + +# Include paths for the executable target +target_include_directories(${PROJECT_NAME} + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/../.. + ${SDK_DIR}/CMSIS/Include + ${SDK_DIR}/devices/MIMXRT1064 + ${SDK_DIR}/drivers + ${SDK_DIR}/board + ${SDK_DIR}/utilities + ${SDK_DIR}/components/uart + ${TX_USER_FILE_DIR} +) + +# Link libraries +target_link_libraries(${PROJECT_NAME} + PRIVATE + board_bsp + threadx + mcux_sdk +) + +# Apply GCC linker script and print memory usage (utilities.cmake function) +set_target_linker(${PROJECT_NAME} "${CMAKE_CURRENT_SOURCE_DIR}/../../startup/MIMXRT1064xxxxx_flexspi_nor.ld") + +# Post-build commands to generate raw .bin and .hex files +post_build(${PROJECT_NAME}) diff --git a/NXP/MIMXRT1064-EVK/app/main.c b/NXP/MIMXRT1064-EVK/app/demos/threadx_basic/main.c similarity index 100% rename from NXP/MIMXRT1064-EVK/app/main.c rename to NXP/MIMXRT1064-EVK/app/demos/threadx_basic/main.c diff --git a/NXP/MIMXRT1064-EVK/app/syscalls.c b/NXP/MIMXRT1064-EVK/app/syscalls.c index fa3d9e88..2411304a 100644 --- a/NXP/MIMXRT1064-EVK/app/syscalls.c +++ b/NXP/MIMXRT1064-EVK/app/syscalls.c @@ -8,7 +8,7 @@ * SPDX-License-Identifier: MIT * * Contributors: - * Ali Eissa - 2026 NXP i.MX RT1064 port. + * Ali Eissa - 2026 version. */ #include diff --git a/NXP/MIMXRT1064-EVK/app/sysmem.c b/NXP/MIMXRT1064-EVK/app/sysmem.c index 98235ab8..4d7954bc 100644 --- a/NXP/MIMXRT1064-EVK/app/sysmem.c +++ b/NXP/MIMXRT1064-EVK/app/sysmem.c @@ -8,7 +8,7 @@ * SPDX-License-Identifier: MIT * * Contributors: - * Ali Eissa - 2026 NXP i.MX RT1064 port. + * Ali Eissa - 2026 version. */ #include diff --git a/NXP/MIMXRT1064-EVK/cmake/utilities.cmake b/NXP/MIMXRT1064-EVK/cmake/utilities.cmake index b86454da..d584424d 100644 --- a/NXP/MIMXRT1064-EVK/cmake/utilities.cmake +++ b/NXP/MIMXRT1064-EVK/cmake/utilities.cmake @@ -20,8 +20,8 @@ function(post_build TARGET) elseif(CMAKE_C_COMPILER_ID STREQUAL "GNU") add_custom_target(${TARGET}.bin ALL DEPENDS ${TARGET} - COMMAND ${CMAKE_OBJCOPY} -Obinary ${TARGET}.elf ${TARGET}.bin - COMMAND ${CMAKE_OBJCOPY} -Oihex ${TARGET}.elf ${TARGET}.hex) + COMMAND ${CMAKE_OBJCOPY} -Obinary $ $/${TARGET}.bin + COMMAND ${CMAKE_OBJCOPY} -Oihex $ $/${TARGET}.hex) else() message(FATAL_ERROR "Unknown CMAKE_C_COMPILER_ID ${CMAKE_C_COMPILER_ID}") endif() diff --git a/NXP/MIMXRT1064-EVK/renode/mimxrt1064-evk.repl b/NXP/MIMXRT1064-EVK/renode/mimxrt1064-evk.repl index 81b1f8cd..ee18a571 100644 --- a/NXP/MIMXRT1064-EVK/renode/mimxrt1064-evk.repl +++ b/NXP/MIMXRT1064-EVK/renode/mimxrt1064-evk.repl @@ -36,3 +36,14 @@ adc1: adc2: referenceVoltage: 3.3 + +// Ethernet Physical Layer (KSZ8081 PHY at address 2 on enet) +phy: Network.EthernetPhysicalLayer @ enet 2 + Id1: 0x0022 + Id2: 0x1560 + BasicControl: 0x3100 + BasicStatus: 0x782D + AutoNegotiationAdvertisement: 0x01E1 + AutoNegotiationLinkPartnerBasePageAbility: 0x01E1 + VendorSpecific14: 0x0116 + VendorSpecific15: 0x0080 diff --git a/NXP/MIMXRT1064-EVK/renode/mimxrt1064-evk.resc b/NXP/MIMXRT1064-EVK/renode/mimxrt1064-evk.resc index ba8f9226..6ba323b0 100644 --- a/NXP/MIMXRT1064-EVK/renode/mimxrt1064-evk.resc +++ b/NXP/MIMXRT1064-EVK/renode/mimxrt1064-evk.resc @@ -1,5 +1,5 @@ :name: MIMXRT1064-EVK ThreadX Demo -:description: This script runs the Eclipse ThreadX demo on NXP i.MX RT1064-EVK. +:description: This script runs the Eclipse ThreadX & NetX Duo demo on NXP i.MX RT1064-EVK. mach create "mimxrt1064-evk" @@ -8,6 +8,17 @@ machine LoadPlatformDescription $platform $bin?=$ORIGIN/../build/mimxrt1064_threadx.elf +# Create Ethernet Switch and connect ENET peripheral +emulation CreateSwitch "switch" +connector Connect sysbus.enet switch + +# Host TAP networking configuration (for ICMP ping and UDP/TCP echo from host PC): +# On Windows, install OpenVPN/TAP adapter named "renode-tap" configured with IP 192.168.0.1 / 255.255.255.0. +# On Linux, create tap interface: `sudo ip tuntap add mode tap tap0 && sudo ifconfig tap0 192.168.0.1 up` +# Uncomment below lines to bridge the simulated switch to your host TAP device: +# emulation CreateTap "renode-tap" "tap" +# connector Connect host.tap switch + showAnalyzer sysbus.lpuart1 macro reset diff --git a/NXP/MIMXRT1064-EVK/renode/mimxrt1064-network-multinode.resc b/NXP/MIMXRT1064-EVK/renode/mimxrt1064-network-multinode.resc new file mode 100644 index 00000000..88be9668 --- /dev/null +++ b/NXP/MIMXRT1064-EVK/renode/mimxrt1064-network-multinode.resc @@ -0,0 +1,51 @@ +:name: MIMXRT1064-EVK NetX Duo Two-Node Virtual Network Verification +:description: This script creates two MIMXRT1064-EVK nodes connected via a virtual Ethernet switch: +: - "server": Echo Server on 192.168.0.100 (ICMP Ping, UDP port 7, TCP port 7) +: - "client": Verification Client on 192.168.0.101 (tests ICMP, UDP Echo, TCP Echo) + +# 1. Create Virtual Ethernet Switch +emulation CreateSwitch "switch" + +# 2. Server Machine (192.168.0.100) +mach create "server" +machine LoadPlatformDescription $ORIGIN/mimxrt1064-evk.repl +connector Connect sysbus.enet switch +showAnalyzer sysbus.lpuart1 + +$bin_server?=$ORIGIN/../build/mimxrt1064_threadx.elf +macro reset_server +""" + cpu VectorTableOffset 0x70002000 + sysbus LoadELF $bin_server + cpu PC `sysbus ReadDoubleWord 0x70002004` + cpu SP `sysbus ReadDoubleWord 0x70002000` +""" +runMacro $reset_server + +# 3. Client Machine (192.168.0.101) +mach create "client" +machine LoadPlatformDescription $ORIGIN/mimxrt1064-evk.repl +connector Connect sysbus.enet switch +showAnalyzer sysbus.lpuart1 + +$bin_client?=$ORIGIN/../build/mimxrt1064_client.elf +macro reset_client +""" + cpu VectorTableOffset 0x70002000 + sysbus LoadELF $bin_client + cpu PC `sysbus ReadDoubleWord 0x70002004` + cpu SP `sysbus ReadDoubleWord 0x70002000` +""" +runMacro $reset_client + +# 4. Global reset macro to reset both nodes simultaneously +macro reset +""" + mach set "server" + runMacro $reset_server + mach set "client" + runMacro $reset_client +""" + +# 5. Start Simulation +start diff --git a/NXP/MIMXRT1064-EVK/scripts/build.ps1 b/NXP/MIMXRT1064-EVK/scripts/build.ps1 index e688610d..a0cd9c99 100644 --- a/NXP/MIMXRT1064-EVK/scripts/build.ps1 +++ b/NXP/MIMXRT1064-EVK/scripts/build.ps1 @@ -11,7 +11,8 @@ param( [switch]$Clean, - [switch]$Rebuild + [switch]$Rebuild, + [string]$Demo = "netx_echo" ) $BoardDir = Resolve-Path "$PSScriptRoot/.." @@ -21,8 +22,9 @@ $NUM_JOBS = 4 Write-Host "==========================================" Write-Host "NXP MIMXRT1064-EVK - Build Script" Write-Host "==========================================" -Write-Host "Board Dir: $BoardDir" -Write-Host "Build Dir: $BUILD_DIR" +Write-Host "Board Dir: $BoardDir" +Write-Host "Build Dir: $BUILD_DIR" +Write-Host "Active Demo: $Demo" Write-Host "" # Check for ARM GCC compiler @@ -48,11 +50,20 @@ if (!(Test-Path $BUILD_DIR)) { Push-Location $BUILD_DIR -# Reconfigure if CMakeCache.txt or build.ninja is missing, or if forced -if (!(Test-Path "CMakeCache.txt") -or !(Test-Path "build.ninja") -or $Rebuild) { - Write-Host "[INFO] Configuring CMake..." +# Reconfigure if CMakeCache.txt or build.ninja is missing, or demo changed, or if forced +$needConfig = !(Test-Path "CMakeCache.txt") -or !(Test-Path "build.ninja") -or $Rebuild +if (!$needConfig -and (Test-Path "CMakeCache.txt")) { + $cachedDemo = (Select-String -Path "CMakeCache.txt" -Pattern "^ACTIVE_DEMO:STRING=(.*)$" | ForEach-Object { $_.Matches.Groups[1].Value.Trim() }) + if ($cachedDemo -ne $Demo) { + $needConfig = $true + } +} + +if ($needConfig) { + Write-Host "[INFO] Configuring CMake for demo: $Demo..." cmake -G Ninja ` "-DCMAKE_BUILD_TYPE=Release" ` + "-DACTIVE_DEMO=$Demo" ` .. if ($LASTEXITCODE -ne 0) { Write-Host "[ERROR] CMake configuration failed!" -ForegroundColor Red @@ -63,22 +74,24 @@ if (!(Test-Path "CMakeCache.txt") -or !(Test-Path "build.ninja") -or $Rebuild) { Write-Host "" } -Write-Host "[INFO] Building with $NUM_JOBS parallel jobs..." -if (Get-Command ninja -ErrorAction SilentlyContinue) { - ninja -j $NUM_JOBS -} else { - cmake --build . --parallel $NUM_JOBS --config Release -} - -$buildExitCode = $LASTEXITCODE -Pop-Location - -if ($buildExitCode -ne 0) { +# Run build using Ninja +Write-Host "[INFO] Building target with Ninja ($NUM_JOBS parallel jobs)..." +ninja -j $NUM_JOBS +if ($LASTEXITCODE -ne 0) { Write-Host "[ERROR] Build failed!" -ForegroundColor Red + Pop-Location exit 1 } Write-Host "" -Write-Host "==========================================" -Write-Host "[OK] Build completed successfully!" -Write-Host "==========================================" +Write-Host "[SUCCESS] Build finished successfully!" -ForegroundColor Green +Write-Host "Server Firmware ELF: $(Join-Path $BUILD_DIR 'mimxrt1064_threadx.elf')" +Write-Host "Server Firmware BIN: $(Join-Path $BUILD_DIR 'mimxrt1064_threadx.bin')" +Write-Host "Server Firmware HEX: $(Join-Path $BUILD_DIR 'mimxrt1064_threadx.hex')" +if (Test-Path (Join-Path $BUILD_DIR 'mimxrt1064_client.elf')) { + Write-Host "Client Firmware ELF: $(Join-Path $BUILD_DIR 'mimxrt1064_client.elf')" + Write-Host "Client Firmware BIN: $(Join-Path $BUILD_DIR 'mimxrt1064_client.bin')" + Write-Host "Client Firmware HEX: $(Join-Path $BUILD_DIR 'mimxrt1064_client.hex')" +} + +Pop-Location diff --git a/NXP/MIMXRT1064-EVK/scripts/build.sh b/NXP/MIMXRT1064-EVK/scripts/build.sh index a202f82f..48d5327e 100644 --- a/NXP/MIMXRT1064-EVK/scripts/build.sh +++ b/NXP/MIMXRT1064-EVK/scripts/build.sh @@ -19,12 +19,14 @@ NUM_JOBS=4 CLEAN=0 REBUILD=0 +DEMO="netx_echo" # Parse arguments while [[ "$#" -gt 0 ]]; do case $1 in --clean) CLEAN=1 ;; --rebuild) REBUILD=1 ;; + --demo) DEMO="$2"; shift ;; *) echo "Unknown parameter passed: $1"; exit 1 ;; esac shift @@ -33,8 +35,9 @@ done echo "==========================================" echo "NXP MIMXRT1064-EVK - Build Script (POSIX)" echo "==========================================" -echo "Board Dir: ${BOARD_DIR}" -echo "Build Dir: ${BUILD_DIR}" +echo "Board Dir: ${BOARD_DIR}" +echo "Build Dir: ${BUILD_DIR}" +echo "Active Demo: ${DEMO}" echo "" # Check for ARM GCC compiler @@ -54,24 +57,38 @@ fi mkdir -p "${BUILD_DIR}" cd "${BUILD_DIR}" -# Reconfigure if CMakeCache.txt or build.ninja is missing, or if forced +# Reconfigure if CMakeCache.txt or build.ninja is missing, or demo changed, or if forced +NEED_CONFIG=0 if [ ! -f "CMakeCache.txt" ] || [ ! -f "build.ninja" ] || [ "${REBUILD}" -eq 1 ]; then - echo "[INFO] Configuring CMake..." + NEED_CONFIG=1 +else + CACHED_DEMO=$(grep "^ACTIVE_DEMO:STRING=" CMakeCache.txt 2>/dev/null | cut -d'=' -f2 | tr -d '[:space:]') + if [ "${CACHED_DEMO}" != "${DEMO}" ]; then + NEED_CONFIG=1 + fi +fi + +if [ "${NEED_CONFIG}" -eq 1 ]; then + echo "[INFO] Configuring CMake for demo: ${DEMO}..." cmake -G Ninja \ - -DCMAKE_BUILD_TYPE=Release \ + "-DCMAKE_BUILD_TYPE=Release" \ + "-DACTIVE_DEMO=${DEMO}" \ .. echo "[OK] CMake configured" echo "" fi -echo "[INFO] Building with ${NUM_JOBS} parallel jobs..." -if command -v ninja &> /dev/null; then - ninja -j "${NUM_JOBS}" -else - cmake --build . --parallel "${NUM_JOBS}" --config Release -fi +# Run build using Ninja +echo "[INFO] Building target with Ninja (${NUM_JOBS} parallel jobs)..." +ninja -j ${NUM_JOBS} echo "" -echo "==========================================" -echo "[OK] Build completed successfully!" -echo "==========================================" +echo "[SUCCESS] Build finished successfully!" +echo "Server Firmware ELF: ${BUILD_DIR}/mimxrt1064_threadx.elf" +echo "Server Firmware BIN: ${BUILD_DIR}/mimxrt1064_threadx.bin" +echo "Server Firmware HEX: ${BUILD_DIR}/mimxrt1064_threadx.hex" +if [ -f "${BUILD_DIR}/mimxrt1064_client.elf" ]; then + echo "Client Firmware ELF: ${BUILD_DIR}/mimxrt1064_client.elf" + echo "Client Firmware BIN: ${BUILD_DIR}/mimxrt1064_client.bin" + echo "Client Firmware HEX: ${BUILD_DIR}/mimxrt1064_client.hex" +fi diff --git a/NXP/MIMXRT1064-EVK/scripts/fetch_sdk.ps1 b/NXP/MIMXRT1064-EVK/scripts/fetch_sdk.ps1 index 420f7ef9..76d585a7 100644 --- a/NXP/MIMXRT1064-EVK/scripts/fetch_sdk.ps1 +++ b/NXP/MIMXRT1064-EVK/scripts/fetch_sdk.ps1 @@ -132,6 +132,12 @@ try { param([string]$Uri, [string]$OutFile, [int]$MaxAttempts = 4) for ($i = 1; $i -le $MaxAttempts; $i++) { try { + if (Get-Command curl.exe -ErrorAction SilentlyContinue) { + & curl.exe --retry 3 --retry-delay 2 -fsSL $Uri -o $OutFile + if ($LASTEXITCODE -eq 0 -and (Test-Path $OutFile) -and ((Get-Item $OutFile).Length -gt 0)) { + return + } + } Invoke-WebRequest -Uri $Uri -OutFile $OutFile -UseBasicParsing -TimeoutSec 30 return } @@ -163,16 +169,18 @@ try { Download-WithRetry -Uri $item.Remote -OutFile $dest } - # Download official GNU GCC Linker Script & Startup File for reference in lib/mcux-sdk/board/ - Write-Host "[INFO] Downloading official NXP GNU GCC Linker Script and Startup File into board directory..." - $nxpGccBase = "https://raw.githubusercontent.com/nxp-mcuxpresso/mcux-sdk/main/devices/MIMXRT1064/gcc" - $ldDestBoard = Join-Path $BoardFilesDir "MIMXRT1064xxxxx_flexspi_nor.ld" - $startupDestBoard = Join-Path $BoardFilesDir "startup_MIMXRT1064.S" - - Download-WithRetry -Uri "$nxpGccBase/MIMXRT1064xxxxx_flexspi_nor.ld" -OutFile $ldDestBoard - Download-WithRetry -Uri "$nxpGccBase/startup_MIMXRT1064.S" -OutFile $startupDestBoard - - Write-Host "[OK] Board support and official GCC reference files downloaded" + # Copy official GNU GCC Linker Script & Startup File from DFP pack into board directory + Write-Host "[INFO] Copying official NXP GNU GCC Linker Script and Startup File into board directory..." + $gccSource = Join-Path $packExtract "gcc" + if (Test-Path $gccSource) { + if (Test-Path "$gccSource/MIMXRT1064xxxxx_flexspi_nor.ld") { + Copy-Item -Path "$gccSource/MIMXRT1064xxxxx_flexspi_nor.ld" -Destination $BoardFilesDir -Force + } + if (Test-Path "$gccSource/startup_MIMXRT1064.S") { + Copy-Item -Path "$gccSource/startup_MIMXRT1064.S" -Destination $BoardFilesDir -Force + } + } + Write-Host "[OK] Board support and official GCC reference files copied" Write-Host "" # 3. Fetch CMSIS Core headers (standard ARM CMSIS-Core include files) @@ -186,6 +194,28 @@ try { Write-Host "[OK] CMSIS Core headers copied" Write-Host "" + # 4. Fetch official NXP KSZ8081 PHY driver (100% stock upstream) + Write-Host "[INFO] Downloading official KSZ8081 PHY driver..." + $phyRawBase = "https://raw.githubusercontent.com/eclipse-threadx/getting-started/master/NXP/MIMXRT1060-EVK/lib/MIMXRT1060-evk/src/components/phyksz8081" + $phyDestDir = Join-Path $ComponentsDir "phy" + New-Item -ItemType Directory -Path $phyDestDir -Force | Out-Null + Download-WithRetry -Uri "$phyRawBase/fsl_phy.c" -OutFile (Join-Path $phyDestDir "fsl_phy.c") + Download-WithRetry -Uri "$phyRawBase/fsl_phy.h" -OutFile (Join-Path $phyDestDir "fsl_phy.h") + Write-Host "[OK] Stock KSZ8081 PHY driver downloaded" + Write-Host "" + + # 5. Fetch official NetX Duo NXP Ethernet driver (100% stock upstream) + Write-Host "[INFO] Downloading official NetX Duo NXP Ethernet driver..." + $netxRawBase = "https://raw.githubusercontent.com/eclipse-threadx/getting-started/master/NXP/MIMXRT1060-EVK/lib/netx_driver" + $netxDriverDestDir = Join-Path $DriversDir "netx_driver" + $netxDriverGnuDir = Join-Path $netxDriverDestDir "gnu" + New-Item -ItemType Directory -Path $netxDriverGnuDir -Force | Out-Null + Download-WithRetry -Uri "$netxRawBase/src/nx_driver_imxrt1062.c" -OutFile (Join-Path $netxDriverDestDir "nx_driver_imxrt1062.c") + Download-WithRetry -Uri "$netxRawBase/src/nx_driver_imxrt1062.h" -OutFile (Join-Path $netxDriverDestDir "nx_driver_imxrt1062.h") + Download-WithRetry -Uri "$netxRawBase/src/gnu/nx_driver_imxrt1062_low_level.S" -OutFile (Join-Path $netxDriverGnuDir "nx_driver_imxrt1062_low_level.S") + Write-Host "[OK] Stock NetX Duo NXP Ethernet driver downloaded" + Write-Host "" + Write-Host "==========================================" Write-Host "[SUCCESS] NXP i.MX RT1064 drivers successfully fetched!" Write-Host "==========================================" diff --git a/NXP/MIMXRT1064-EVK/scripts/fetch_sdk.sh b/NXP/MIMXRT1064-EVK/scripts/fetch_sdk.sh index b0a6e439..c89fa6df 100644 --- a/NXP/MIMXRT1064-EVK/scripts/fetch_sdk.sh +++ b/NXP/MIMXRT1064-EVK/scripts/fetch_sdk.sh @@ -113,12 +113,16 @@ curl -fsSL "${RAW_BASE}/dcd.h" -o "${BOARD_FILES_DIR}/dcd.h" curl -fsSL "${RAW_BASE}/xip/evkmimxrt1064_flexspi_nor_config.c" -o "${BOARD_FILES_DIR}/evkmimxrt1064_flexspi_nor_config.c" curl -fsSL "${RAW_BASE}/xip/evkmimxrt1064_flexspi_nor_config.h" -o "${BOARD_FILES_DIR}/evkmimxrt1064_flexspi_nor_config.h" -echo "[INFO] Downloading official NXP GNU GCC Linker Script and Startup File into board directory..." -NXP_GCC_BASE="https://raw.githubusercontent.com/nxp-mcuxpresso/mcux-sdk/main/devices/MIMXRT1064/gcc" -curl --retry 3 -fsSL "${NXP_GCC_BASE}/MIMXRT1064xxxxx_flexspi_nor.ld" -o "${BOARD_FILES_DIR}/MIMXRT1064xxxxx_flexspi_nor.ld" -curl --retry 3 -fsSL "${NXP_GCC_BASE}/startup_MIMXRT1064.S" -o "${BOARD_FILES_DIR}/startup_MIMXRT1064.S" - -echo "[OK] Board support and official GCC reference files downloaded" +echo "[INFO] Copying official NXP GNU GCC Linker Script and Startup File into board directory..." +if [ -d "${PACK_EXTRACT}/gcc" ]; then + if [ -f "${PACK_EXTRACT}/gcc/MIMXRT1064xxxxx_flexspi_nor.ld" ]; then + cp "${PACK_EXTRACT}/gcc/MIMXRT1064xxxxx_flexspi_nor.ld" "${BOARD_FILES_DIR}/" + fi + if [ -f "${PACK_EXTRACT}/gcc/startup_MIMXRT1064.S" ]; then + cp "${PACK_EXTRACT}/gcc/startup_MIMXRT1064.S" "${BOARD_FILES_DIR}/" + fi +fi +echo "[OK] Board support and official GCC reference files copied" echo "" # 3. Fetch CMSIS Core headers @@ -129,6 +133,26 @@ cp -r "${CMSIS_CLONE_DIR}/CMSIS/Core/Include/"* "${CMSIS_INCLUDE_DEST}/" echo "[OK] CMSIS Core headers copied" echo "" +# 4. Fetch official NXP KSZ8081 PHY driver (100% stock upstream) +echo "[INFO] Downloading official KSZ8081 PHY driver..." +PHY_RAW_BASE="https://raw.githubusercontent.com/eclipse-threadx/getting-started/master/NXP/MIMXRT1060-EVK/lib/MIMXRT1060-evk/src/components/phyksz8081" +mkdir -p "${COMPONENTS_DIR}/phy" +curl --retry 3 -fsSL "${PHY_RAW_BASE}/fsl_phy.c" -o "${COMPONENTS_DIR}/phy/fsl_phy.c" +curl --retry 3 -fsSL "${PHY_RAW_BASE}/fsl_phy.h" -o "${COMPONENTS_DIR}/phy/fsl_phy.h" +echo "[OK] Stock KSZ8081 PHY driver downloaded" +echo "" + +# 5. Fetch official NetX Duo NXP Ethernet driver (100% stock upstream) +echo "[INFO] Downloading official NetX Duo NXP Ethernet driver..." +NETX_RAW_BASE="https://raw.githubusercontent.com/eclipse-threadx/getting-started/master/NXP/MIMXRT1060-EVK/lib/netx_driver" +NETX_DIR="${DRIVERS_DIR}/netx_driver" +mkdir -p "${NETX_DIR}/gnu" +curl --retry 3 -fsSL "${NETX_RAW_BASE}/src/nx_driver_imxrt1062.c" -o "${NETX_DIR}/nx_driver_imxrt1062.c" +curl --retry 3 -fsSL "${NETX_RAW_BASE}/src/nx_driver_imxrt1062.h" -o "${NETX_DIR}/nx_driver_imxrt1062.h" +curl --retry 3 -fsSL "${NETX_RAW_BASE}/src/gnu/nx_driver_imxrt1062_low_level.S" -o "${NETX_DIR}/gnu/nx_driver_imxrt1062_low_level.S" +echo "[OK] Stock NetX Duo NXP Ethernet driver downloaded" +echo "" + echo "==========================================" echo "[SUCCESS] NXP i.MX RT1064 drivers successfully fetched!" echo "==========================================" diff --git a/NXP/MIMXRT1064-EVK/scripts/simulate.ps1 b/NXP/MIMXRT1064-EVK/scripts/simulate.ps1 index 3d2ba2ad..3fba4e35 100644 --- a/NXP/MIMXRT1064-EVK/scripts/simulate.ps1 +++ b/NXP/MIMXRT1064-EVK/scripts/simulate.ps1 @@ -9,16 +9,32 @@ # Contributors: # Ali Eissa - 2026 version. +param( + [string]$Resc +) + $BoardDir = Resolve-Path "$PSScriptRoot/.." -$ElfPath = Join-Path $BoardDir "build/mimxrt1064_threadx.elf" -$RescRelPath = "renode/mimxrt1064-evk.resc" -$RescFullPath = Join-Path $BoardDir $RescRelPath +$ServerElf = Join-Path $BoardDir "build/mimxrt1064_threadx.elf" +$ClientElf = Join-Path $BoardDir "build/mimxrt1064_client.elf" -if (-not (Test-Path $ElfPath)) { - Write-Error "Binary $ElfPath not found. Please build the project first using .\scripts\build.ps1" +if (-not (Test-Path $ServerElf)) { + Write-Error "Binary $ServerElf not found. Please build the project first using .\scripts\build.ps1" exit 1 } +# Determine RESC script: custom argument, or auto-detect multi-node vs single-node +if ($Resc) { + $RescRelPath = $Resc + $Mode = "Custom Script" +} elseif (Test-Path $ClientElf) { + $RescRelPath = "renode/mimxrt1064-network-multinode.resc" + $Mode = "Multi-Node Network Verification (Server: 192.168.0.100, Client: 192.168.0.101)" +} else { + $RescRelPath = "renode/mimxrt1064-evk.resc" + $Mode = "Single-Node Demo" +} +$RescFullPath = Join-Path $BoardDir $RescRelPath + # Find Renode executable $RenodeExe = (Get-Command renode -ErrorAction SilentlyContinue).Source if (-not $RenodeExe -and (Test-Path "C:\Program Files\Renode\renode.exe")) { @@ -34,10 +50,14 @@ Write-Host "==========================================" Write-Host "Starting Renode Simulation" Write-Host "==========================================" Write-Host "Renode: $RenodeExe" +Write-Host "Mode: $Mode" Write-Host "Script: $RescFullPath" -Write-Host "Target ELF: $ElfPath" +Write-Host "Server ELF: $ServerElf" +if (Test-Path $ClientElf) { + Write-Host "Client ELF: $ClientElf" +} Write-Host "" -Write-Host "Opening Renode Monitor and LPUART1 terminal analyzer..." +Write-Host "Opening Renode Monitor and LPUART1 terminal analyzer(s)..." Write-Host "To exit Renode, type 'quit' in the Renode Monitor or close the window." Write-Host "==========================================" diff --git a/NXP/MIMXRT1064-EVK/scripts/simulate.sh b/NXP/MIMXRT1064-EVK/scripts/simulate.sh index f47a8a43..80552a54 100644 --- a/NXP/MIMXRT1064-EVK/scripts/simulate.sh +++ b/NXP/MIMXRT1064-EVK/scripts/simulate.sh @@ -14,14 +14,25 @@ set -e SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" BOARD_DIR="$(cd "${SCRIPT_DIR}/.." && pwd)" -ELF_PATH="${BOARD_DIR}/build/mimxrt1064_threadx.elf" -RESC_REL_PATH="renode/mimxrt1064-evk.resc" +SERVER_ELF="${BOARD_DIR}/build/mimxrt1064_threadx.elf" +CLIENT_ELF="${BOARD_DIR}/build/mimxrt1064_client.elf" -if [ ! -f "${ELF_PATH}" ]; then - echo "[ERROR] Binary ${ELF_PATH} not found. Please build first using ./scripts/build.sh" +if [ ! -f "${SERVER_ELF}" ]; then + echo "[ERROR] Binary ${SERVER_ELF} not found. Please build first using ./scripts/build.sh" exit 1 fi +if [ -n "$1" ]; then + RESC_REL_PATH="$1" + MODE="Custom Script" +elif [ -f "${CLIENT_ELF}" ]; then + RESC_REL_PATH="renode/mimxrt1064-network-multinode.resc" + MODE="Multi-Node Network Verification (Server: 192.168.0.100, Client: 192.168.0.101)" +else + RESC_REL_PATH="renode/mimxrt1064-evk.resc" + MODE="Single-Node Demo" +fi + RENODE_CMD="renode" if ! command -v renode &> /dev/null; then if [ -f "/opt/renode/renode" ]; then @@ -35,8 +46,12 @@ fi echo "==========================================" echo "Starting Renode Simulation" echo "==========================================" +echo "Mode: ${MODE}" echo "Script: ${BOARD_DIR}/${RESC_REL_PATH}" -echo "Target ELF: ${ELF_PATH}" +echo "Server ELF: ${SERVER_ELF}" +if [ -f "${CLIENT_ELF}" ]; then + echo "Client ELF: ${CLIENT_ELF}" +fi echo "" cd "${BOARD_DIR}" From f27f4ad0e546354980f2cf1dd1b6ee1af0c02b2f Mon Sep 17 00:00:00 2001 From: Ali Eissa Date: Sun, 13 Sep 2026 21:34:04 +0400 Subject: [PATCH 07/11] feat(mimxrt1064): add Hardware TRNG & Network Diagnostic Shell demo Signed-off-by: Ali Eissa Assisted-by: Google DeepMind Antigravity --- NXP/MIMXRT1064-EVK/CMakeLists.txt | 5 +- .../demos/netx_trng_console/CMakeLists.txt | 108 ++++++ .../app/demos/netx_trng_console/client_main.c | 262 +++++++++++++ .../app/demos/netx_trng_console/main.c | 352 ++++++++++++++++++ .../app/demos/netx_trng_console/nx_user.h | 21 ++ NXP/MIMXRT1064-EVK/app/trng.c | 91 +++++ NXP/MIMXRT1064-EVK/app/trng.h | 54 +++ .../renode/mimxrt1064-trng-console.resc | 51 +++ NXP/MIMXRT1064-EVK/scripts/simulate.ps1 | 17 +- NXP/MIMXRT1064-EVK/scripts/simulate.sh | 11 + 10 files changed, 969 insertions(+), 3 deletions(-) create mode 100644 NXP/MIMXRT1064-EVK/app/demos/netx_trng_console/CMakeLists.txt create mode 100644 NXP/MIMXRT1064-EVK/app/demos/netx_trng_console/client_main.c create mode 100644 NXP/MIMXRT1064-EVK/app/demos/netx_trng_console/main.c create mode 100644 NXP/MIMXRT1064-EVK/app/demos/netx_trng_console/nx_user.h create mode 100644 NXP/MIMXRT1064-EVK/app/trng.c create mode 100644 NXP/MIMXRT1064-EVK/app/trng.h create mode 100644 NXP/MIMXRT1064-EVK/renode/mimxrt1064-trng-console.resc diff --git a/NXP/MIMXRT1064-EVK/CMakeLists.txt b/NXP/MIMXRT1064-EVK/CMakeLists.txt index 46546835..6a26381a 100644 --- a/NXP/MIMXRT1064-EVK/CMakeLists.txt +++ b/NXP/MIMXRT1064-EVK/CMakeLists.txt @@ -28,8 +28,8 @@ project(mimxrt1064_threadx C CXX ASM) # Ensure executable output (elf, bin, hex) goes directly to the top-level build directory set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}") -# Select the active demo to build (default: netx_echo, or threadx_basic) -set(ACTIVE_DEMO "netx_echo" CACHE STRING "Active demo name to build: netx_echo, threadx_basic") +# Select the active demo to build (default: netx_echo, netx_trng_console, or threadx_basic) +set(ACTIVE_DEMO "netx_echo" CACHE STRING "Active demo name to build: netx_echo, netx_trng_console, threadx_basic") # Set up paths for MCUXpresso SDK set(SDK_DIR "${CMAKE_CURRENT_LIST_DIR}/lib/mcux-sdk") @@ -118,6 +118,7 @@ add_library(board_bsp OBJECT app/startup/tx_initialize_low_level.S app/board_init.c app/console.c + app/trng.c app/sysmem.c app/syscalls.c ) diff --git a/NXP/MIMXRT1064-EVK/app/demos/netx_trng_console/CMakeLists.txt b/NXP/MIMXRT1064-EVK/app/demos/netx_trng_console/CMakeLists.txt new file mode 100644 index 00000000..a3a4ec5c --- /dev/null +++ b/NXP/MIMXRT1064-EVK/app/demos/netx_trng_console/CMakeLists.txt @@ -0,0 +1,108 @@ +# Copyright (c) 2026 Eclipse ThreadX contributors +# +# 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. + +# Server Executable Target (mimxrt1064_threadx) +add_executable(${PROJECT_NAME} + main.c +) + +# Set compile definitions for server +target_compile_definitions(${PROJECT_NAME} + PRIVATE + 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 +) + +# Include paths for server +target_include_directories(${PROJECT_NAME} + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/../.. + ${SDK_DIR}/drivers/netx_driver + ${SDK_DIR}/CMSIS/Include + ${SDK_DIR}/devices/MIMXRT1064 + ${SDK_DIR}/drivers + ${SDK_DIR}/board + ${SDK_DIR}/utilities + ${SDK_DIR}/components/uart + ${SDK_DIR}/components/phy + ${TX_USER_FILE_DIR} +) + +# Link libraries for server +target_link_libraries(${PROJECT_NAME} + PRIVATE + board_bsp + threadx + netxduo + netx_imxrt_driver + mcux_sdk +) + +# Apply GCC linker script and post-build outputs for server +set_target_linker(${PROJECT_NAME} "${CMAKE_CURRENT_SOURCE_DIR}/../../startup/MIMXRT1064xxxxx_flexspi_nor.ld") +post_build(${PROJECT_NAME}) + +# Automated Verification Client Executable Target (mimxrt1064_client) +set(CLIENT_TARGET "mimxrt1064_client") +add_executable(${CLIENT_TARGET} + client_main.c +) + +# Set compile definitions for client +target_compile_definitions(${CLIENT_TARGET} + PRIVATE + NETX_CLIENT_NODE=1 + 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 +) + +# Include paths for client +target_include_directories(${CLIENT_TARGET} + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/../.. + ${SDK_DIR}/drivers/netx_driver + ${SDK_DIR}/CMSIS/Include + ${SDK_DIR}/devices/MIMXRT1064 + ${SDK_DIR}/drivers + ${SDK_DIR}/board + ${SDK_DIR}/utilities + ${SDK_DIR}/components/uart + ${SDK_DIR}/components/phy + ${TX_USER_FILE_DIR} +) + +# Link libraries for client +target_link_libraries(${CLIENT_TARGET} + PRIVATE + board_bsp + threadx + netxduo + netx_imxrt_driver_client + mcux_sdk +) + +# Apply GCC linker script and post-build outputs for client +set_target_linker(${CLIENT_TARGET} "${CMAKE_CURRENT_SOURCE_DIR}/../../startup/MIMXRT1064xxxxx_flexspi_nor.ld") +post_build(${CLIENT_TARGET}) diff --git a/NXP/MIMXRT1064-EVK/app/demos/netx_trng_console/client_main.c b/NXP/MIMXRT1064-EVK/app/demos/netx_trng_console/client_main.c new file mode 100644 index 00000000..f95fff17 --- /dev/null +++ b/NXP/MIMXRT1064-EVK/app/demos/netx_trng_console/client_main.c @@ -0,0 +1,262 @@ +/* + * Copyright (c) 2026 Eclipse ThreadX contributors + * + * 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. + */ + +#include "board_init.h" +#include "console.h" +#include "ansi_colors.h" +#include "tx_api.h" +#include "nx_api.h" +#include +#include + +#define DEMO_STACK_SIZE 2048 +#define PACKET_SIZE 1536 +#define PACKET_POOL_SIZE ((PACKET_SIZE + sizeof(NX_PACKET)) * 24) +#define ARP_CACHE_SIZE 512 +#define CONSOLE_SERVER_PORT 23 + +#define CLIENT_IP_ADDRESS_VAL IP_ADDRESS(192, 168, 0, 101) +#define SERVER_IP_ADDRESS IP_ADDRESS(192, 168, 0, 100) +#define NETWORK_MASK_VAL IP_ADDRESS(255, 255, 255, 0) +#define GATEWAY_ADDRESS_VAL IP_ADDRESS(192, 168, 0, 1) + + + +static ULONG client_ip_stack[DEMO_STACK_SIZE / sizeof(ULONG)]; +static ULONG client_test_stack[DEMO_STACK_SIZE / sizeof(ULONG)]; +static ULONG client_arp_cache[ARP_CACHE_SIZE / sizeof(ULONG)]; + +__attribute__((section(".NonCacheable"))) +static uint8_t client_packet_pool_area[PACKET_POOL_SIZE]; + +static NX_PACKET_POOL client_pool; +static NX_IP client_ip; +static TX_THREAD client_test_thread; + +VOID nx_driver_imx(NX_IP_DRIVER *driver_req_ptr); +static void client_test_thread_entry(ULONG thread_input); + +int main(void) +{ + board_init(); + + printf(ANSI_BOLD ANSI_YELLOW "\r\n==================================================\r\n" ANSI_RESET); + printf(ANSI_BOLD ANSI_YELLOW " MIMXRT1064 TRNG & Console Verification Client\r\n" ANSI_RESET); + printf(ANSI_BOLD ANSI_YELLOW " Running on Simulated Node 2 (192.168.0.101)\r\n" ANSI_RESET); + printf(ANSI_BOLD ANSI_YELLOW "==================================================\r\n\r\n" ANSI_RESET); + + tx_kernel_enter(); + + return 0; +} + +void tx_application_define(void *first_unused_memory) +{ + (void)first_unused_memory; + UINT status; + + nx_system_initialize(); + + status = nx_packet_pool_create(&client_pool, "Client Packet Pool", + PACKET_SIZE, client_packet_pool_area, PACKET_POOL_SIZE); + if (status != NX_SUCCESS) + { + printf(TAG_CLIENT " " MSG_ERROR " Failed to create packet pool: 0x%02X\r\n", status); + return; + } + + status = nx_ip_create(&client_ip, "Client IP", CLIENT_IP_ADDRESS_VAL, + NETWORK_MASK_VAL, &client_pool, nx_driver_imx, + client_ip_stack, DEMO_STACK_SIZE, 1); + if (status != NX_SUCCESS) + { + printf(TAG_CLIENT " " MSG_ERROR " Failed to create IP instance: 0x%02X\r\n", status); + return; + } + + nx_ip_gateway_address_set(&client_ip, GATEWAY_ADDRESS_VAL); + nx_arp_enable(&client_ip, (VOID *)client_arp_cache, ARP_CACHE_SIZE); + nx_icmp_enable(&client_ip); + nx_tcp_enable(&client_ip); + + status = tx_thread_create(&client_test_thread, "Client Test Thread", + client_test_thread_entry, 0, + client_test_stack, DEMO_STACK_SIZE, + 10, 10, TX_NO_TIME_SLICE, TX_AUTO_START); + if (status != TX_SUCCESS) + { + printf(TAG_CLIENT " " MSG_ERROR " Failed to create test thread: 0x%02X\r\n", status); + } +} + +static UINT send_and_receive(NX_TCP_SOCKET *socket, const char *cmd, char *rx_buf, size_t rx_buf_size, ULONG timeout) +{ + NX_PACKET *tx_packet = NX_NULL; + NX_PACKET *rx_packet = NX_NULL; + UINT status; + + status = nx_packet_allocate(&client_pool, &tx_packet, NX_TCP_PACKET, TX_WAIT_FOREVER); + if (status != NX_SUCCESS) return status; + + nx_packet_data_append(tx_packet, (VOID *)cmd, strlen(cmd), &client_pool, TX_WAIT_FOREVER); + status = nx_tcp_socket_send(socket, tx_packet, TX_WAIT_FOREVER); + if (status != NX_SUCCESS) return status; + + status = nx_tcp_socket_receive(socket, &rx_packet, timeout); + if (status == NX_SUCCESS && rx_packet != NX_NULL) + { + ULONG len = rx_packet->nx_packet_length; + if (len >= rx_buf_size) len = rx_buf_size - 1; + memcpy(rx_buf, rx_packet->nx_packet_prepend_ptr, len); + rx_buf[len] = '\0'; + nx_packet_release(rx_packet); + } + return status; +} + +static void client_test_thread_entry(ULONG thread_input) +{ + (void)thread_input; + UINT status; + ULONG actual_status; + int all_passed = 1; + char buffer[256]; + + printf(TAG_CLIENT " " MSG_INFO " Bringing Ethernet Link UP...\r\n"); + status = nx_ip_driver_direct_command(&client_ip, NX_LINK_ENABLE, &actual_status); + if (status == NX_SUCCESS || status == NX_ALREADY_ENABLED) + { + printf(TAG_CLIENT " " MSG_SUCCESS " Ethernet link is UP!\r\n"); + } + + printf(TAG_CLIENT " " MSG_INFO " Waiting for network convergence...\r\n"); + tx_thread_sleep(150); + + printf("\r\n" ANSI_BOLD ANSI_CYAN "==================================================\r\n" ANSI_RESET); + printf(ANSI_BOLD ANSI_CYAN " Starting Hardware TRNG & Console Verification Suite\r\n" ANSI_RESET); + printf(ANSI_CYAN " Target Server: 192.168.0.100 (Port %d)\r\n" ANSI_RESET, CONSOLE_SERVER_PORT); + printf(ANSI_BOLD ANSI_CYAN "==================================================\r\n\r\n" ANSI_RESET); + + /* Test 1: ICMP Ping */ + printf(TAG_CLIENT " [Test 1/5] Testing ICMP Ping to 192.168.0.100...\r\n"); + NX_PACKET *ping_resp = NX_NULL; + status = nx_icmp_ping(&client_ip, SERVER_IP_ADDRESS, "TRNG_Ping", 9, &ping_resp, 200); + if (status == NX_SUCCESS && ping_resp != NX_NULL) + { + printf(TAG_CLIENT " " MSG_SUCCESS " ICMP Ping successful! Response from 192.168.0.100\r\n"); + nx_packet_release(ping_resp); + } + else + { + printf(TAG_CLIENT " " MSG_ERROR " ICMP Ping failed: 0x%02X\r\n", status); + all_passed = 0; + } + + tx_thread_sleep(30); + + /* Test 2: Connect to TCP Port 23 */ + printf("\r\n" TAG_CLIENT " [Test 2/5] Connecting to TRNG Console Server on port %d...\r\n", CONSOLE_SERVER_PORT); + NX_TCP_SOCKET client_socket; + status = nx_tcp_socket_create(&client_ip, &client_socket, "Client Shell Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, + 512, NX_NULL, NX_NULL); + if (status != NX_SUCCESS) + { + printf(TAG_CLIENT " " MSG_ERROR " Failed to create TCP socket: 0x%02X\r\n", status); + return; + } + + nx_tcp_client_socket_bind(&client_socket, NX_ANY_PORT, TX_WAIT_FOREVER); + status = nx_tcp_client_socket_connect(&client_socket, SERVER_IP_ADDRESS, CONSOLE_SERVER_PORT, 200); + if (status == NX_SUCCESS) + { + printf(TAG_CLIENT " " MSG_SUCCESS " TCP Connected! Receiving greeting banner...\r\n"); + + /* Receive welcome banner */ + NX_PACKET *banner_packet = NX_NULL; + if (nx_tcp_socket_receive(&client_socket, &banner_packet, 100) == NX_SUCCESS) + { + nx_packet_release(banner_packet); + } + + /* Test 3: Query Hardware TRNG Entropy */ + printf("\r\n" TAG_CLIENT " [Test 3/5] Querying on-chip TRNG entropy ('trng')...\r\n"); + memset(buffer, 0, sizeof(buffer)); + status = send_and_receive(&client_socket, "trng\r\n", buffer, sizeof(buffer), 200); + if (status == NX_SUCCESS && strstr(buffer, "[TRNG] Hardware Entropy:")) + { + printf(TAG_CLIENT " " MSG_SUCCESS " Hardware TRNG Entropy Received:\r\n %s", buffer); + } + else + { + printf(TAG_CLIENT " " MSG_ERROR " TRNG query failed (status: 0x%02X)\r\n", status); + all_passed = 0; + } + + /* Test 4: Remote LED Control */ + printf("\r\n" TAG_CLIENT " [Test 4/5] Testing Remote LED Control ('led toggle')...\r\n"); + memset(buffer, 0, sizeof(buffer)); + status = send_and_receive(&client_socket, "led toggle\r\n", buffer, sizeof(buffer), 200); + if (status == NX_SUCCESS && strstr(buffer, "[LED] State: TOGGLED")) + { + printf(TAG_CLIENT " " MSG_SUCCESS " Remote LED toggle acknowledged by server!\r\n"); + } + else + { + printf(TAG_CLIENT " " MSG_ERROR " LED control failed (status: 0x%02X)\r\n", status); + all_passed = 0; + } + + /* Test 5: Target Info Query */ + printf("\r\n" TAG_CLIENT " [Test 5/5] Querying processor and RTOS status ('info')...\r\n"); + memset(buffer, 0, sizeof(buffer)); + status = send_and_receive(&client_socket, "info\r\n", buffer, sizeof(buffer), 200); + if (status == NX_SUCCESS && strstr(buffer, "MIMXRT1064-EVK")) + { + printf(TAG_CLIENT " " MSG_SUCCESS " Processor & ThreadX status verified:\r\n %s", buffer); + } + else + { + printf(TAG_CLIENT " " MSG_ERROR " Info query failed (status: 0x%02X)\r\n", status); + all_passed = 0; + } + + /* Graceful disconnect */ + send_and_receive(&client_socket, "quit\r\n", buffer, sizeof(buffer), 50); + nx_tcp_socket_disconnect(&client_socket, 10); + } + else + { + printf(TAG_CLIENT " " MSG_ERROR " Failed to connect to server: 0x%02X\r\n", status); + all_passed = 0; + } + + nx_tcp_client_socket_unbind(&client_socket); + nx_tcp_socket_delete(&client_socket); + + printf("\r\n==================================================\r\n"); + if (all_passed) + { + printf(ANSI_BOLD ANSI_GREEN " [VERIFICATION SUCCESS] ALL TRNG & CONSOLE TESTS PASSED!\r\n" ANSI_RESET); + } + else + { + printf(ANSI_BOLD ANSI_RED " [VERIFICATION FAILED] One or more tests failed.\r\n" ANSI_RESET); + } + printf("==================================================\r\n\r\n"); + + while (1) + { + tx_thread_sleep(100); + } +} diff --git a/NXP/MIMXRT1064-EVK/app/demos/netx_trng_console/main.c b/NXP/MIMXRT1064-EVK/app/demos/netx_trng_console/main.c new file mode 100644 index 00000000..b107371b --- /dev/null +++ b/NXP/MIMXRT1064-EVK/app/demos/netx_trng_console/main.c @@ -0,0 +1,352 @@ +/* + * Copyright (c) 2026 Eclipse ThreadX contributors + * + * 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. + */ + +#include "board_init.h" +#include "console.h" +#include "ansi_colors.h" +#include "trng.h" +#include "tx_api.h" +#include "nx_api.h" +#include +#include + +#define DEMO_STACK_SIZE 2048 +#define PACKET_SIZE 1536 +#define PACKET_POOL_SIZE ((PACKET_SIZE + sizeof(NX_PACKET)) * 24) +#define ARP_CACHE_SIZE 512 +#define CONSOLE_SERVER_PORT 23 + +#define IP_ADDRESS_VAL IP_ADDRESS(192, 168, 0, 100) +#define NETWORK_MASK_VAL IP_ADDRESS(255, 255, 255, 0) +#define GATEWAY_ADDRESS_VAL IP_ADDRESS(192, 168, 0, 1) + +#define TAG_SHELL "\x1b[38;5;243m[Shell]" +#define TAG_TRNG "\x1b[38;5;243m[TRNG]" + +/* Memory buffers */ +static ULONG ip_thread_stack[DEMO_STACK_SIZE / sizeof(ULONG)]; +static ULONG heartbeat_thread_stack[DEMO_STACK_SIZE / sizeof(ULONG)]; +static ULONG shell_thread_stack[DEMO_STACK_SIZE / sizeof(ULONG)]; +static ULONG arp_cache_area[ARP_CACHE_SIZE / sizeof(ULONG)]; + +__attribute__((section(".NonCacheable"))) +static uint8_t packet_pool_area[PACKET_POOL_SIZE]; + +/* NetX Duo & ThreadX objects */ +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static TX_THREAD heartbeat_thread; +static TX_THREAD shell_thread; + +/* External driver entry point */ +VOID nx_driver_imx(NX_IP_DRIVER *driver_req_ptr); + +/* Thread prototypes */ +static void heartbeat_thread_entry(ULONG thread_input); +static void shell_thread_entry(ULONG thread_input); + +int main(void) +{ + /* Initialize MPU, clocks (600 MHz), pins, LED GPIO, console, and ENET */ + board_init(); + + /* Initialize on-chip Hardware TRNG */ + trng_init(); + + printf(ANSI_BOLD ANSI_CYAN "\r\n==================================================\r\n" ANSI_RESET); + printf(ANSI_BOLD ANSI_CYAN " Eclipse ThreadX & NetX Duo on NXP i.MX RT1064-EVK\r\n" ANSI_RESET); + printf(ANSI_BOLD ANSI_CYAN " Hardware TRNG & Network Diagnostic Shell (Renode)\r\n" ANSI_RESET); + printf(ANSI_BOLD ANSI_CYAN "==================================================\r\n\r\n" ANSI_RESET); + + printf(TAG_SYSTEM " " MSG_INFO "Core Clock: %lu MHz | Tick Rate: %u Hz\r\n" ANSI_RESET, + SystemCoreClock / 1000000UL, TX_TIMER_TICKS_PER_SECOND); + printf(TAG_TRNG " " MSG_INFO "On-chip True Random Number Generator initialized @ 0x400CC000\r\n" ANSI_RESET); + + /* Enter ThreadX kernel */ + tx_kernel_enter(); + + return 0; +} + +void tx_application_define(void *first_unused_memory) +{ + (void)first_unused_memory; + UINT status; + + printf(TAG_NETWORK " " MSG_INFO "Initializing NetX Duo System...\r\n" ANSI_RESET); + nx_system_initialize(); + + /* 1. Create packet pool in NonCacheable memory */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", + PACKET_SIZE, packet_pool_area, PACKET_POOL_SIZE); + if (status != NX_SUCCESS) + { + printf(TAG_NETWORK " " MSG_ERROR "Failed to create packet pool: 0x%02X\r\n" ANSI_RESET, status); + return; + } + printf(TAG_NETWORK " " MSG_SUCCESS "Packet pool created (%u bytes in NonCacheable memory)\r\n" ANSI_RESET, + (unsigned int)sizeof(packet_pool_area)); + + /* 2. Create IP instance */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS_VAL, + NETWORK_MASK_VAL, &pool_0, nx_driver_imx, + ip_thread_stack, DEMO_STACK_SIZE, 1); + if (status != NX_SUCCESS) + { + printf(TAG_NETWORK " " MSG_ERROR "Failed to create IP instance: 0x%02X\r\n" ANSI_RESET, status); + return; + } + printf(TAG_NETWORK " " MSG_SUCCESS "IP instance created\r\n" ANSI_RESET); + + /* 3. Gateway & Services */ + nx_ip_gateway_address_set(&ip_0, GATEWAY_ADDRESS_VAL); + + printf(TAG_NETWORK " " MSG_INFO "Enabling ARP...\r\n" ANSI_RESET); + nx_arp_enable(&ip_0, (VOID *)arp_cache_area, ARP_CACHE_SIZE); + + printf(TAG_NETWORK " " MSG_INFO "Enabling ICMP (Ping responder)...\r\n" ANSI_RESET); + nx_icmp_enable(&ip_0); + + printf(TAG_NETWORK " " MSG_INFO "Enabling TCP...\r\n" ANSI_RESET); + nx_tcp_enable(&ip_0); + + /* 4. Create Heartbeat Thread */ + status = tx_thread_create(&heartbeat_thread, "Heartbeat Thread", + heartbeat_thread_entry, 0, + heartbeat_thread_stack, DEMO_STACK_SIZE, + 15, 15, TX_NO_TIME_SLICE, TX_AUTO_START); + if (status != TX_SUCCESS) + { + printf(TAG_SYSTEM " " MSG_ERROR "Failed to create Heartbeat thread: 0x%02X\r\n" ANSI_RESET, status); + } + + /* 5. Create TRNG Console Shell Thread */ + status = tx_thread_create(&shell_thread, "TRNG Shell Thread", + shell_thread_entry, 0, + shell_thread_stack, DEMO_STACK_SIZE, + 10, 10, TX_NO_TIME_SLICE, TX_AUTO_START); + if (status != TX_SUCCESS) + { + printf(TAG_SYSTEM " " MSG_ERROR "Failed to create Shell thread: 0x%02X\r\n" ANSI_RESET, status); + } + + printf(TAG_NETWORK " " MSG_SUCCESS "Network threads registered successfully.\r\n" ANSI_RESET); +} + +static void heartbeat_thread_entry(ULONG thread_input) +{ + (void)thread_input; + UINT status; + ULONG actual_status; + ULONG ip_address, network_mask; + + printf(TAG_NETWORK " " MSG_INFO "Bringing Ethernet Link UP...\r\n" ANSI_RESET); + status = nx_ip_driver_direct_command(&ip_0, NX_LINK_ENABLE, &actual_status); + if (status == NX_SUCCESS || status == NX_ALREADY_ENABLED) + { + printf(TAG_NETWORK " " MSG_SUCCESS "Ethernet link is UP!\r\n" ANSI_RESET); + } + else + { + printf(TAG_NETWORK " " MSG_ERROR "nx_ip_driver_direct_command NX_LINK_ENABLE status: 0x%02X\r\n" ANSI_RESET, status); + } + + nx_ip_address_get(&ip_0, &ip_address, &network_mask); + printf("\r\n" ANSI_BOLD ANSI_GREEN "================ Network Ready ================\r\n" ANSI_RESET); + printf(ANSI_GREEN " Static IPv4 : %lu.%lu.%lu.%lu\r\n" ANSI_RESET, + (ip_address >> 24) & 0xFF, (ip_address >> 16) & 0xFF, + (ip_address >> 8) & 0xFF, ip_address & 0xFF); + printf(ANSI_GREEN " Subnet Mask : %lu.%lu.%lu.%lu\r\n" ANSI_RESET, + (network_mask >> 24) & 0xFF, (network_mask >> 16) & 0xFF, + (network_mask >> 8) & 0xFF, network_mask & 0xFF); + printf(ANSI_GREEN " Services : ICMP Ping, Hardware TRNG Shell (TCP Port %d)\r\n" ANSI_RESET, CONSOLE_SERVER_PORT); + printf(ANSI_BOLD ANSI_GREEN "===============================================\r\n\r\n" ANSI_RESET); + + while (1) + { + tx_thread_sleep(50); + USER_LED_TOGGLE(); + } +} + +static void send_tcp_response(NX_TCP_SOCKET *socket, const char *msg) +{ + NX_PACKET *tx_packet = NX_NULL; + UINT status; + size_t len = strlen(msg); + + status = nx_packet_allocate(&pool_0, &tx_packet, NX_TCP_PACKET, TX_WAIT_FOREVER); + if (status == NX_SUCCESS) + { + nx_packet_data_append(tx_packet, (VOID *)msg, len, &pool_0, TX_WAIT_FOREVER); + nx_tcp_socket_send(socket, tx_packet, TX_WAIT_FOREVER); + } +} + +static void shell_thread_entry(ULONG thread_input) +{ + NX_TCP_SOCKET shell_socket; + NX_PACKET *packet_ptr; + UINT status; + char line_buffer[128]; + char resp_buffer[256]; + + (void)thread_input; + + status = nx_tcp_socket_create(&ip_0, &shell_socket, "TRNG Shell Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, + 1024, NX_NULL, NX_NULL); + if (status != NX_SUCCESS) + { + printf(TAG_SHELL " " MSG_ERROR "Failed to create TCP socket: 0x%02X\r\n" ANSI_RESET, status); + return; + } + + printf(TAG_SHELL " " MSG_INFO "TRNG Diagnostic Shell listening on port %d\r\n" ANSI_RESET, CONSOLE_SERVER_PORT); + + while (1) + { + status = nx_tcp_server_socket_listen(&ip_0, CONSOLE_SERVER_PORT, &shell_socket, 5, NX_NULL); + if (status != NX_SUCCESS) + { + nx_tcp_server_socket_unlisten(&ip_0, CONSOLE_SERVER_PORT); + tx_thread_sleep(10); + continue; + } + + status = nx_tcp_server_socket_accept(&shell_socket, NX_WAIT_FOREVER); + if (status == NX_SUCCESS) + { + ULONG peer_ip = 0; + ULONG peer_port = 0; + nx_tcp_socket_peer_info_get(&shell_socket, &peer_ip, &peer_port); + + printf(TAG_SHELL " " MSG_SUCCESS "Client connected from %lu.%lu.%lu.%lu:%lu\r\n" ANSI_RESET, + (peer_ip >> 24) & 0xFF, (peer_ip >> 16) & 0xFF, + (peer_ip >> 8) & 0xFF, peer_ip & 0xFF, peer_port); + + /* Send Welcome Banner */ + send_tcp_response(&shell_socket, + "\r\n==================================================\r\n" + " NXP i.MX RT1064-EVK Hardware TRNG Console\r\n" + " Eclipse ThreadX & NetX Duo Management Shell\r\n" + "==================================================\r\n" + "Type 'help' for available commands.\r\n\r\nmimxrt1064> "); + + while (1) + { + status = nx_tcp_socket_receive(&shell_socket, &packet_ptr, NX_WAIT_FOREVER); + if (status != NX_SUCCESS) + { + break; + } + + ULONG copy_len = packet_ptr->nx_packet_length; + if (copy_len >= sizeof(line_buffer)) + { + copy_len = sizeof(line_buffer) - 1; + } + memcpy(line_buffer, packet_ptr->nx_packet_prepend_ptr, copy_len); + line_buffer[copy_len] = '\0'; + nx_packet_release(packet_ptr); + + /* Trim trailing CRLF */ + char *p = line_buffer + strlen(line_buffer) - 1; + while (p >= line_buffer && (*p == '\r' || *p == '\n' || *p == ' ')) + { + *p-- = '\0'; + } + + if (strlen(line_buffer) == 0) + { + send_tcp_response(&shell_socket, "mimxrt1064> "); + continue; + } + + printf(TAG_SHELL " Received command: '%s'\r\n", line_buffer); + + if (strcmp(line_buffer, "help") == 0) + { + send_tcp_response(&shell_socket, + "Available commands:\r\n" + " trng - Read 4x 32-bit hardware entropy words from on-chip TRNG\r\n" + " info - Print processor clock, memory, and ThreadX ticks\r\n" + " led on|off|toggle - Control or toggle User LED D18\r\n" + " ping - Connection health check\r\n" + " quit - Terminate console session\r\n\r\nmimxrt1064> "); + } + else if (strcmp(line_buffer, "trng") == 0 || strcmp(line_buffer, "rand") == 0) + { + uint32_t r1 = 0, r2 = 0, r3 = 0, r4 = 0; + trng_get_random_u32(&r1); + trng_get_random_u32(&r2); + trng_get_random_u32(&r3); + trng_get_random_u32(&r4); + + snprintf(resp_buffer, sizeof(resp_buffer), + "[TRNG] Hardware Entropy: 0x%08lX 0x%08lX 0x%08lX 0x%08lX\r\n\r\nmimxrt1064> ", + (unsigned long)r1, (unsigned long)r2, (unsigned long)r3, (unsigned long)r4); + printf(TAG_TRNG " Generated entropy: 0x%08lX 0x%08lX 0x%08lX 0x%08lX\r\n", + (unsigned long)r1, (unsigned long)r2, (unsigned long)r3, (unsigned long)r4); + send_tcp_response(&shell_socket, resp_buffer); + } + else if (strcmp(line_buffer, "info") == 0) + { + snprintf(resp_buffer, sizeof(resp_buffer), + "[INFO] Target: NXP MIMXRT1064-EVK (ARM Cortex-M7 @ 600 MHz)\r\n" + "[INFO] RTOS: Eclipse ThreadX | Uptime: %lu ticks\r\n" + "[INFO] TRNG: On-chip hardware entropy engine active @ 0x400CC000\r\n\r\nmimxrt1064> ", + tx_time_get()); + send_tcp_response(&shell_socket, resp_buffer); + } + else if (strncmp(line_buffer, "led", 3) == 0) + { + if (strstr(line_buffer, "on")) + { + USER_LED_ON(); + send_tcp_response(&shell_socket, "[LED] State: ON\r\n\r\nmimxrt1064> "); + } + else if (strstr(line_buffer, "off")) + { + USER_LED_OFF(); + send_tcp_response(&shell_socket, "[LED] State: OFF\r\n\r\nmimxrt1064> "); + } + else + { + USER_LED_TOGGLE(); + send_tcp_response(&shell_socket, "[LED] State: TOGGLED\r\n\r\nmimxrt1064> "); + } + } + else if (strcmp(line_buffer, "ping") == 0) + { + send_tcp_response(&shell_socket, "[PONG] Network connection alive\r\n\r\nmimxrt1064> "); + } + else if (strcmp(line_buffer, "quit") == 0 || strcmp(line_buffer, "exit") == 0) + { + send_tcp_response(&shell_socket, "Goodbye!\r\n"); + break; + } + else + { + send_tcp_response(&shell_socket, "Unknown command. Type 'help' for options.\r\n\r\nmimxrt1064> "); + } + } + + printf(TAG_SHELL " Client disconnected\r\n"); + nx_tcp_socket_disconnect(&shell_socket, 10); + nx_tcp_server_socket_unaccept(&shell_socket); + } + + nx_tcp_server_socket_unlisten(&ip_0, CONSOLE_SERVER_PORT); + } +} diff --git a/NXP/MIMXRT1064-EVK/app/demos/netx_trng_console/nx_user.h b/NXP/MIMXRT1064-EVK/app/demos/netx_trng_console/nx_user.h new file mode 100644 index 00000000..eccf436a --- /dev/null +++ b/NXP/MIMXRT1064-EVK/app/demos/netx_trng_console/nx_user.h @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2026 Eclipse ThreadX contributors + * + * 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. + */ + +#ifndef NX_USER_H +#define NX_USER_H + +#define NX_DISABLE_IPV6 +#define NX_PHYSICAL_HEADER 16 +#define NX_ENABLE_EXTENDED_NOTIFY_SUPPORT + +#endif /* NX_USER_H */ diff --git a/NXP/MIMXRT1064-EVK/app/trng.c b/NXP/MIMXRT1064-EVK/app/trng.c new file mode 100644 index 00000000..6424f67f --- /dev/null +++ b/NXP/MIMXRT1064-EVK/app/trng.c @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2026 Eclipse ThreadX contributors + * + * 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. + */ + +#include "trng.h" +#include "fsl_device_registers.h" +#include "fsl_clock.h" +#include + +#define TRNG_TIMEOUT_CYCLES 1000000UL + +int trng_init(void) +{ + /* Enable TRNG peripheral clock in CCM */ + CLOCK_EnableClock(kCLOCK_Trng); + + /* Check if TRNG is reporting error, clear if needed */ + if (TRNG->MCTL & TRNG_MCTL_ERR_MASK) + { + /* Clear error by resetting to defaults */ + TRNG->MCTL |= TRNG_MCTL_RST_DEF_MASK; + } + + return 0; +} + +int trng_get_random_u32(uint32_t *random_val) +{ + uint32_t timeout = TRNG_TIMEOUT_CYCLES; + + if (!random_val) + { + return -1; + } + + /* Wait for Entropy Valid (ENT_VAL) bit */ + while (!(TRNG->MCTL & TRNG_MCTL_ENT_VAL_MASK)) + { + if (--timeout == 0) + { + return -2; /* Timeout waiting for entropy */ + } + } + + /* Read a 32-bit random word from the first entropy register */ + *random_val = TRNG->ENT[0]; + + return 0; +} + +int trng_get_random_data(void *buffer, size_t length) +{ + uint8_t *out = (uint8_t *)buffer; + size_t offset = 0; + uint32_t rand_word; + int status; + + if (!buffer) + { + return -1; + } + + while (offset < length) + { + status = trng_get_random_u32(&rand_word); + if (status != 0) + { + return status; + } + + size_t chunk = length - offset; + if (chunk > sizeof(uint32_t)) + { + chunk = sizeof(uint32_t); + } + + memcpy(out + offset, &rand_word, chunk); + offset += chunk; + } + + return (int)length; +} diff --git a/NXP/MIMXRT1064-EVK/app/trng.h b/NXP/MIMXRT1064-EVK/app/trng.h new file mode 100644 index 00000000..6e1c0aa9 --- /dev/null +++ b/NXP/MIMXRT1064-EVK/app/trng.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2026 Eclipse ThreadX contributors + * + * 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. + */ + +#ifndef TRNG_H +#define TRNG_H + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Initialize the on-chip True Random Number Generator (TRNG) peripheral. + * Enables TRNG peripheral clock gating and initializes default sampling parameters. + * + * @return 0 on success, non-zero on error. + */ +int trng_init(void); + +/** + * @brief Read a single 32-bit hardware random word from TRNG entropy registers. + * + * @param[out] random_val Pointer to uint32_t to receive the random word. + * @return 0 on success, non-zero on error or timeout. + */ +int trng_get_random_u32(uint32_t *random_val); + +/** + * @brief Fill a buffer with hardware random bytes from TRNG entropy registers. + * + * @param[out] buffer Output buffer to receive random bytes. + * @param[in] length Number of bytes to generate. + * @return Number of bytes filled on success, or negative on error. + */ +int trng_get_random_data(void *buffer, size_t length); + +#ifdef __cplusplus +} +#endif + +#endif /* TRNG_H */ diff --git a/NXP/MIMXRT1064-EVK/renode/mimxrt1064-trng-console.resc b/NXP/MIMXRT1064-EVK/renode/mimxrt1064-trng-console.resc new file mode 100644 index 00000000..ca877e09 --- /dev/null +++ b/NXP/MIMXRT1064-EVK/renode/mimxrt1064-trng-console.resc @@ -0,0 +1,51 @@ +:name: MIMXRT1064-EVK Hardware TRNG & Console Two-Node Verification +:description: This script creates two MIMXRT1064-EVK nodes connected via a virtual Ethernet switch: +: - "server": TRNG Console Server on 192.168.0.100 (TCP Port 23, ICMP Ping) +: - "client": Verification Client on 192.168.0.101 (tests TRNG entropy, LED control, Info) + +# 1. Create Virtual Ethernet Switch +emulation CreateSwitch "switch" + +# 2. Server Machine (192.168.0.100) +mach create "server" +machine LoadPlatformDescription $ORIGIN/mimxrt1064-evk.repl +connector Connect sysbus.enet switch +showAnalyzer sysbus.lpuart1 + +$bin_server?=$ORIGIN/../build/mimxrt1064_threadx.elf +macro reset_server +""" + cpu VectorTableOffset 0x70002000 + sysbus LoadELF $bin_server + cpu PC `sysbus ReadDoubleWord 0x70002004` + cpu SP `sysbus ReadDoubleWord 0x70002000` +""" +runMacro $reset_server + +# 3. Client Machine (192.168.0.101) +mach create "client" +machine LoadPlatformDescription $ORIGIN/mimxrt1064-evk.repl +connector Connect sysbus.enet switch +showAnalyzer sysbus.lpuart1 + +$bin_client?=$ORIGIN/../build/mimxrt1064_client.elf +macro reset_client +""" + cpu VectorTableOffset 0x70002000 + sysbus LoadELF $bin_client + cpu PC `sysbus ReadDoubleWord 0x70002004` + cpu SP `sysbus ReadDoubleWord 0x70002000` +""" +runMacro $reset_client + +# 4. Global reset macro to reset both nodes simultaneously +macro reset +""" + mach set "server" + runMacro $reset_server + mach set "client" + runMacro $reset_client +""" + +# 5. Start Simulation +start diff --git a/NXP/MIMXRT1064-EVK/scripts/simulate.ps1 b/NXP/MIMXRT1064-EVK/scripts/simulate.ps1 index 3fba4e35..842c5de4 100644 --- a/NXP/MIMXRT1064-EVK/scripts/simulate.ps1 +++ b/NXP/MIMXRT1064-EVK/scripts/simulate.ps1 @@ -22,10 +22,25 @@ if (-not (Test-Path $ServerElf)) { exit 1 } -# Determine RESC script: custom argument, or auto-detect multi-node vs single-node +# Determine RESC script: custom argument, or auto-detect based on cached demo +$cachedDemo = "" +$cacheFile = Join-Path $BoardDir "build/CMakeCache.txt" +if (Test-Path $cacheFile) { + $match = Select-String -Path $cacheFile -Pattern "^ACTIVE_DEMO:STRING=(.*)$" + if ($match) { + $cachedDemo = $match.Matches.Groups[1].Value.Trim() + } +} + if ($Resc) { $RescRelPath = $Resc $Mode = "Custom Script" +} elseif ($cachedDemo -eq "netx_trng_console") { + $RescRelPath = "renode/mimxrt1064-trng-console.resc" + $Mode = "Hardware TRNG Console (Server: 192.168.0.100, Client: 192.168.0.101)" +} elseif ($cachedDemo -eq "netx_echo") { + $RescRelPath = "renode/mimxrt1064-network-multinode.resc" + $Mode = "Multi-Node Network Echo Verification (Server: 192.168.0.100, Client: 192.168.0.101)" } elseif (Test-Path $ClientElf) { $RescRelPath = "renode/mimxrt1064-network-multinode.resc" $Mode = "Multi-Node Network Verification (Server: 192.168.0.100, Client: 192.168.0.101)" diff --git a/NXP/MIMXRT1064-EVK/scripts/simulate.sh b/NXP/MIMXRT1064-EVK/scripts/simulate.sh index 80552a54..dcf574be 100644 --- a/NXP/MIMXRT1064-EVK/scripts/simulate.sh +++ b/NXP/MIMXRT1064-EVK/scripts/simulate.sh @@ -22,9 +22,20 @@ if [ ! -f "${SERVER_ELF}" ]; then exit 1 fi +CACHED_DEMO="" +if [ -f "${BOARD_DIR}/build/CMakeCache.txt" ]; then + CACHED_DEMO=$(grep -E "^ACTIVE_DEMO:STRING=" "${BOARD_DIR}/build/CMakeCache.txt" | cut -d'=' -f2 | tr -d ' \r\n') +fi + if [ -n "$1" ]; then RESC_REL_PATH="$1" MODE="Custom Script" +elif [ "$CACHED_DEMO" = "netx_trng_console" ]; then + RESC_REL_PATH="renode/mimxrt1064-trng-console.resc" + MODE="Hardware TRNG Console (Server: 192.168.0.100, Client: 192.168.0.101)" +elif [ "$CACHED_DEMO" = "netx_echo" ]; then + RESC_REL_PATH="renode/mimxrt1064-network-multinode.resc" + MODE="Multi-Node Network Echo Verification (Server: 192.168.0.100, Client: 192.168.0.101)" elif [ -f "${CLIENT_ELF}" ]; then RESC_REL_PATH="renode/mimxrt1064-network-multinode.resc" MODE="Multi-Node Network Verification (Server: 192.168.0.100, Client: 192.168.0.101)" From a3d197c3685230c5847db938270b9da037142aee Mon Sep 17 00:00:00 2001 From: Ali Eissa Date: Mon, 14 Sep 2026 04:47:38 +0400 Subject: [PATCH 08/11] feat(MIMXRT1064): Renode CI for MIMXRT1064 and CMake architecture overhaul Signed-off-by: Ali Eissa Assisted-by: Google DeepMind Antigravity --- NXP/MIMXRT1064-EVK/CMakeLists.txt | 48 ++- NXP/MIMXRT1064-EVK/NOTICE.md | 34 ++- NXP/MIMXRT1064-EVK/README.md | 286 +++++++++++++----- NXP/MIMXRT1064-EVK/app/MIMXRT1062.h | 13 + .../app/demos/netx_echo/CMakeLists.txt | 17 +- .../demos/netx_trng_console/CMakeLists.txt | 17 +- .../app/demos/netx_trng_console/nx_user.h | 21 -- .../app/demos/threadx_basic/CMakeLists.txt | 14 +- .../app/demos/threadx_basic/main.c | 2 +- .../startup/MIMXRT1064xxxxx_flexspi_nor.ld | 4 + .../app/startup/tx_initialize_low_level.S | 2 +- NXP/MIMXRT1064-EVK/cmake/utilities.cmake | 10 +- .../demos/netx_echo => lib/netxduo}/nx_user.h | 0 NXP/MIMXRT1064-EVK/renode/mimxrt1064-evk.resc | 11 + .../renode/mimxrt1064-headless-multinode.resc | 43 +++ .../renode/mimxrt1064-headless-single.resc | 26 ++ .../renode/mimxrt1064-network-multinode.resc | 11 + .../renode/mimxrt1064-trng-console.resc | 11 + NXP/MIMXRT1064-EVK/scripts/build.ps1 | 32 +- NXP/MIMXRT1064-EVK/scripts/build.sh | 31 +- NXP/MIMXRT1064-EVK/scripts/fetch_sdk.ps1 | 2 +- NXP/MIMXRT1064-EVK/scripts/fetch_sdk.sh | 2 +- NXP/MIMXRT1064-EVK/scripts/simulate.ps1 | 107 +++++-- NXP/MIMXRT1064-EVK/scripts/simulate.sh | 122 ++++++-- NXP/MIMXRT1064-EVK/scripts/test_headless.ps1 | 153 ++++++++++ NXP/MIMXRT1064-EVK/scripts/test_headless.sh | 150 +++++++++ 26 files changed, 939 insertions(+), 230 deletions(-) delete mode 100644 NXP/MIMXRT1064-EVK/app/demos/netx_trng_console/nx_user.h rename NXP/MIMXRT1064-EVK/{app/demos/netx_echo => lib/netxduo}/nx_user.h (100%) create mode 100644 NXP/MIMXRT1064-EVK/renode/mimxrt1064-headless-multinode.resc create mode 100644 NXP/MIMXRT1064-EVK/renode/mimxrt1064-headless-single.resc create mode 100644 NXP/MIMXRT1064-EVK/scripts/test_headless.ps1 create mode 100644 NXP/MIMXRT1064-EVK/scripts/test_headless.sh diff --git a/NXP/MIMXRT1064-EVK/CMakeLists.txt b/NXP/MIMXRT1064-EVK/CMakeLists.txt index 6a26381a..83dad0c1 100644 --- a/NXP/MIMXRT1064-EVK/CMakeLists.txt +++ b/NXP/MIMXRT1064-EVK/CMakeLists.txt @@ -25,11 +25,8 @@ include(utilities) # Define the Project project(mimxrt1064_threadx C CXX ASM) -# Ensure executable output (elf, bin, hex) goes directly to the top-level build directory -set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}") - -# Select the active demo to build (default: netx_echo, netx_trng_console, or threadx_basic) -set(ACTIVE_DEMO "netx_echo" CACHE STRING "Active demo name to build: netx_echo, netx_trng_console, threadx_basic") +# 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") @@ -37,17 +34,14 @@ 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 Auto-Detection -# Check if the active demo uses NetX Duo by looking for nx_user.h -if(EXISTS "${CMAKE_CURRENT_LIST_DIR}/app/demos/${ACTIVE_DEMO}/nx_user.h") - set(USE_NETXDUO ON) +# 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(USE_NETXDUO OFF) + set(NX_USER_FILE "${CMAKE_CURRENT_LIST_DIR}/lib/netxduo/nx_user.h" CACHE STRING "Enable NetX Duo user configuration" FORCE) endif() -# Check if the active demo has custom tx_user.h; otherwise fallback to lib/threadx/tx_user.h -if(EXISTS "${CMAKE_CURRENT_LIST_DIR}/app/demos/${ACTIVE_DEMO}/tx_user.h") +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() @@ -59,12 +53,10 @@ endif() set(THREADX_DIR "${CMAKE_CURRENT_LIST_DIR}/../../libs/threadx") add_subdirectory(${THREADX_DIR} threadx) -if(USE_NETXDUO) - # Compile NetX Duo TCP/IP Stack from root shared libs submodule - set(NXD_ENABLE_FILE_SERVERS OFF CACHE BOOL "Disable FileX dependency in NetX Duo" FORCE) - set(NETXDUO_DIR "${CMAKE_CURRENT_LIST_DIR}/../../libs/netxduo") - add_subdirectory(${NETXDUO_DIR} netxduo) -endif() +# 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 "${CMAKE_CURRENT_LIST_DIR}/../../libs/netxduo") +add_subdirectory(${NETXDUO_DIR} netxduo) # Compile the NXP MCUXpresso Driver & Board Library as an Object Library set(SDK_TARGET mcux_sdk) @@ -153,9 +145,8 @@ target_link_libraries(board_bsp threadx ) -# 2. Define conditional NetX Duo driver library target -if(USE_NETXDUO) - add_library(netx_imxrt_driver OBJECT +# 2. Define NetX Duo driver library targets (cached for networking demos) +add_library(netx_imxrt_driver OBJECT ${SDK_DIR}/drivers/netx_driver/nx_driver_imxrt1062.c ${SDK_DIR}/drivers/netx_driver/gnu/nx_driver_imxrt1062_low_level.S ${SDK_DIR}/components/phy/fsl_phy.c @@ -179,7 +170,7 @@ if(USE_NETXDUO) ${SDK_DIR}/drivers/netx_driver ${SDK_DIR}/components/phy ${CMAKE_CURRENT_LIST_DIR}/app - ${CMAKE_CURRENT_LIST_DIR}/app/demos/${ACTIVE_DEMO} + ${CMAKE_CURRENT_LIST_DIR}/lib/netxduo ${SDK_DIR}/CMSIS/Include ${SDK_DIR}/devices/MIMXRT1064 ${SDK_DIR}/drivers @@ -222,7 +213,7 @@ if(USE_NETXDUO) ${SDK_DIR}/drivers/netx_driver ${SDK_DIR}/components/phy ${CMAKE_CURRENT_LIST_DIR}/app - ${CMAKE_CURRENT_LIST_DIR}/app/demos/${ACTIVE_DEMO} + ${CMAKE_CURRENT_LIST_DIR}/lib/netxduo ${SDK_DIR}/CMSIS/Include ${SDK_DIR}/devices/MIMXRT1064 ${SDK_DIR}/drivers @@ -239,7 +230,12 @@ if(USE_NETXDUO) mcux_sdk ) target_compile_options(netx_imxrt_driver_client PRIVATE -Wno-unused-variable) -endif() -# 3. Add the active demo subdirectory to build the executable target -add_subdirectory(app/demos/${ACTIVE_DEMO}) +# 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() diff --git a/NXP/MIMXRT1064-EVK/NOTICE.md b/NXP/MIMXRT1064-EVK/NOTICE.md index 854858e9..d60251c0 100644 --- a/NXP/MIMXRT1064-EVK/NOTICE.md +++ b/NXP/MIMXRT1064-EVK/NOTICE.md @@ -1,34 +1,37 @@ # Third-Party Software Notices -This directory contains build automation scripts and configurations that download and compile third-party software components. This notice lists the licenses and copyrights applicable to those components. +This directory contains third-party software components included in the repository as well as build automation scripts and configurations that download and compile external dependencies. This notice lists the licenses and copyrights applicable to those components. --- -## 1. NXP MCUXpresso SDK Drivers & Device Support -* **Source**: https://github.com/nxp-mcuxpresso/mcuxsdk-core / https://mcuxpresso.nxp.com/ +## 1. NXP MCUXpresso SDK Drivers, Device Support & Startup Files +* **Source**: https://github.com/nxp-mcuxpresso/mcuxsdk-core / https://github.com/nxp-mcuxpresso/mcuxsdk-examples / https://mcuxpresso.nxp.com +* **Location**: `app/startup/startup_mimxrt1064.S`, `app/startup/MIMXRT1064xxxxx_flexspi_nor.ld`, and `lib/mcux-sdk/` * **License**: BSD 3-Clause ```text -Copyright 2016-2026 NXP -All rights reserved. +Copyright (c) 2015-2016, Freescale Semiconductor, Inc. +Copyright 2018-2025 NXP + +The BSD 3 Clause License Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: -1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. +1. Redistributions of source code must retain the above copyright notice, this +list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. 3. Neither the name of the copyright holder nor the names of its contributors - may be used to endorse or promote products derived from this software - without specific prior written permission. +may be used to endorse or promote products derived from this software without +specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR @@ -41,7 +44,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. --- ## 2. ARM CMSIS Core -* **Source**: https://github.com/ARM-software/CMSIS_5 / https://github.com/STMicroelectronics/cmsis-core +* **Source**: https://github.com/ARM-software/CMSIS_5 +* **Location**: `lib/mcux-sdk/CMSIS/Include/` * **License**: Apache License 2.0 ```text diff --git a/NXP/MIMXRT1064-EVK/README.md b/NXP/MIMXRT1064-EVK/README.md index e625089f..944aded2 100644 --- a/NXP/MIMXRT1064-EVK/README.md +++ b/NXP/MIMXRT1064-EVK/README.md @@ -1,115 +1,259 @@ -# NXP i.MX RT1064-EVK Board Support Package & Demos +# NXP i.MX RT1064-EVK Board Enablement Demos -This directory contains the Board Support Package (BSP) and build environment for running the **Eclipse ThreadX RTOS** and **NetX Duo** on the **NXP i.MX RT1064-EVK** evaluation board (ARM Cortex-M7 @ 600 MHz). +This directory contains the Board Support Package (BSP) and build configurations for running the **Eclipse ThreadX RTOS** and **NetX Duo TCP/IP stack** on the **NXP i.MX RT1064-EVK** evaluation board (ARM Cortex-M7 @ 600 MHz). -The project is designed to run seamlessly both in the **Antmicro Renode** simulation framework and on physical silicon. +The project features a decoupled Board Support Package (`board_bsp`) that hides all low-level hardware initializations (clocks, power, caches, MPU regions, pin muxing, Ethernet MAC/PHY descriptors, and on-chip cryptographic peripherals) from the high-level application code. + +> [!NOTE] +> **Hardware Verification Status**: *Simulated in Renode, Pending Physical Hardware Verification* +> +> All peripheral drivers, hardware cryptographic subsystems, and network stacks documented in this repository have been fully verified under multi-node system emulation in Antmicro Renode. Flashing instructions for physical silicon follow standard NXP OpenSDA, Segger J-Link, pyOCD, and MCUXpresso workflows as detailed in the [Physical Board Deployment & Flashing](#physical-board-deployment--flashing) section below. --- -## Hardware Configuration +## Supported Demos -* **Development Board**: MIMXRT1064-EVK -* **Microcontroller**: NXP i.MX RT1064 (MIMXRT1064DVL6A, ARM Cortex-M7 @ 600 MHz) -* **Flash Memory**: 4 MB internal FlexSPI NOR Flash (XIP) -* **Internal SRAM**: 1 MB on-chip RAM (Configurable as ITCM, DTCM, and OCRAM) -* **Debug Serial Console**: LPUART1 (115,200 baud, 8N1) -* **User LED**: GPIO1 Pin 9 (`GPIO_AD_B0_09`) / User LED D18 (Green) -* **User Button**: GPIO5 Pin 0 (SW8 WAKEUP button) -* **Virtual Networking**: ENET1 (10/100M Fast Ethernet MAC via KSZ8081 PHY) +Each demo outputs into its own isolated directory in `build/app/demos//`: + +| Demo Name | Description | Output Directory | +| :--- | :--- | :--- | +| **`threadx_basic`** | Core ThreadX RTOS demo: preemptive thread scheduling, timer callbacks, and User LED D18 heartbeat blinking. | `build/app/demos/threadx_basic/` | +| **`netx_echo`** | NetX Duo networking demo: KSZ8081 Ethernet PHY, ARP, ICMP Ping responder, UDP echo (port 7), and TCP echo server (port 7). | `build/app/demos/netx_echo/` | +| **`netx_trng_console`** *(Default)* | Hardware cryptographic True Random Number Generator (TRNG @ `0x400CC000`) with an interactive TCP diagnostic management shell on port 23. | `build/app/demos/netx_trng_console/` | --- -## Project Structure - -```text -NXP/MIMXRT1064-EVK/ -├── CMakeLists.txt # Top-level CMake build configuration -├── NOTICE.md # Third-party licensing notices (NXP BSD-3 & CMSIS) -├── README.md # This documentation file -├── app/ -│ ├── main.c # ThreadX application entry, Heartbeat & Worker threads -│ ├── board_init.c / .h # Clocks (600 MHz), MPU, pin muxing & User LED init -│ ├── console.c / .h # LPUART1 serial driver & POSIX printf retargeting -│ ├── syscalls.c / sysmem.c # Minimal C runtime system call stubs -│ └── startup/ -│ ├── startup_mimxrt1064.S # NXP vector table & reset handler -│ ├── tx_initialize_low_level.S # ThreadX Cortex-M7 low-level init & SysTick -│ └── MIMXRT1064xxxxx_flexspi_nor.ld # FlexSPI NOR XIP GNU linker script -├── cmake/ -│ ├── arm-gcc-cortex-m7.cmake # CPU architecture and FPU definitions -│ ├── arm-gcc-cortex-toolchain.cmake # GNU toolchain discovery and compiler flags -│ └── utilities.cmake # Elf-to-bin/hex conversion and linker macros -├── lib/ -│ ├── threadx/ -│ │ └── tx_user.h # ThreadX configuration (hardware FPU enabled, 100 Hz tick) -│ └── mcux-sdk/ # Official NXP SDK drivers (fetched via script) -├── renode/ -│ ├── mimxrt1064-evk.repl # Board platform description (memory, LED, button) -│ └── mimxrt1064-evk.resc # Renode simulation script (LPUART1 analyzer & LED logging) -└── scripts/ - ├── fetch_sdk.ps1 / .sh # Download official NXP drivers, device headers & CMSIS - ├── build.ps1 / .sh # One-command build script with Ninja/CMake - └── simulate.ps1 / .sh # Launch Renode simulation with serial monitor -``` +## Hardware Overview + +* **Evaluation Board**: NXP MIMXRT1064-EVK (ARM Cortex-M7 @ 600 MHz) +* **Memory**: 4 MB on-chip FlexSPI NOR Flash (`0x70000000`), 1 MB on-chip SRAM (ITCM, DTCM, NonCacheable OCRAM) +* **Serial Console**: LPUART1 via OpenSDA micro-USB (`J41`), 115,200 baud, 8N1 +* **User LED & Button**: Green LED `D18` (`GPIO1_IO09`), SW8 WAKEUP button (`GPIO5_IO00`) +* **Ethernet**: ENET MAC + Microchip KSZ8081RNA PHY via RMII +* **TRNG Hardware**: On-chip True Random Number Generator (`0x400CC000`) --- ## Prerequisites -Before building, ensure the following cross-compilation tools are installed and present on your `PATH`: - -* **ARM GNU Toolchain** (`arm-none-eabi-gcc` 10.3 or newer) -* **CMake** (version 3.5 or newer) -* **Ninja** (or **Make**) +* **ARM GNU Toolchain** (`arm-none-eabi-gcc` 10.3+) +* **CMake** (3.20+) and **Ninja** (recommended) or Make * **Git** (for downloading SDK dependencies) -* **Antmicro Renode** (v1.15 or newer, for simulation) +* **Antmicro Renode** (1.15.3+, for simulation) --- ## Quick Start Guide ### 1. Download SDK Dependencies -Run the driver fetcher script to retrieve official NXP MCUXpresso SDK drivers, CMSIS device headers, and board files: +Download the stock NXP MCUXpresso SDK drivers, CMSIS headers, and board files: -* **On Windows (PowerShell)**: +* **Windows**: ```powershell powershell -ExecutionPolicy Bypass -File .\scripts\fetch_sdk.ps1 ``` -* **On Linux / macOS (Bash)**: +* **Linux / macOS**: + ```bash + chmod +x ./scripts/fetch_sdk.sh && ./scripts/fetch_sdk.sh + ``` + +### 2. Build the Demos + +#### Option A: Build All Demos (Default & Recommended) +Build all three demos at once. Once built, you can switch between simulations instantly without rebuilding! + +* **Windows**: + ```powershell + powershell -ExecutionPolicy Bypass -File .\scripts\build.ps1 + ``` +* **Linux / macOS**: + ```bash + chmod +x ./scripts/build.sh && ./scripts/build.sh + ``` +* **Direct CMake**: ```bash - chmod +x ./scripts/fetch_sdk.sh - ./scripts/fetch_sdk.sh + cmake -B build -G Ninja -DACTIVE_DEMO=all + cmake --build build ``` -### 2. Build the Project -Compile the application, vendor drivers, and Eclipse ThreadX kernel: +#### Option B: Build a Specific Demo +To build only one specific demo: + +```powershell +# Windows PowerShell +.\scripts\build.ps1 -Demo threadx_basic +.\scripts\build.ps1 -Demo netx_echo +.\scripts\build.ps1 -Demo netx_trng_console +``` + +```bash +# Linux / macOS Bash +./scripts/build.sh -d threadx_basic +./scripts/build.sh -d netx_echo +./scripts/build.sh -d netx_trng_console +``` + +Each demo's artifacts (`.elf`, `.bin`, `.hex`, `.map`) are placed in `build/app/demos//`. + +--- + +## Renode Simulation + +The project includes preconfigured Renode emulation environments for both single-node and multi-node scenarios. + +### 1. Interactive Simulation +Simulate any demo simply by passing the `-Demo` configuration variable: -* **On Windows (PowerShell)**: +* **Windows (PowerShell)**: ```powershell - powershell -ExecutionPolicy Bypass -File .\scripts\build.ps1 -Rebuild + # ThreadX Core Basic (single node) + powershell -ExecutionPolicy Bypass -File .\scripts\simulate.ps1 -Demo threadx_basic + + # NetX Duo Network Echo (multi-node server + client) + powershell -ExecutionPolicy Bypass -File .\scripts\simulate.ps1 -Demo netx_echo + + # Hardware TRNG Diagnostic Console (multi-node server + client) + powershell -ExecutionPolicy Bypass -File .\scripts\simulate.ps1 -Demo netx_trng_console ``` -* **On Linux / macOS (Bash)**: + +* **Linux / macOS (Bash)**: ```bash - chmod +x ./scripts/build.sh - ./scripts/build.sh --rebuild + ./scripts/simulate.sh -d threadx_basic + ./scripts/simulate.sh -d netx_echo + ./scripts/simulate.sh -d netx_trng_console ``` -### 3. Run the Simulation in Renode -Launch the interactive Renode simulation: +#### Deterministic Seeding Option: +For deterministic execution and repeatable TRNG random sequences in simulation, pass `-Seed `: +```powershell +powershell -ExecutionPolicy Bypass -File .\scripts\simulate.ps1 -Demo netx_trng_console -Seed 12345 +``` +```bash +./scripts/simulate.sh -d netx_trng_console -s 12345 +``` -* **On Windows (PowerShell)**: +### 2. Headless Automated Regression Testing (CI/CD) +The project provides headless test runners (`test_headless.ps1` and `test_headless.sh`) designed for continuous integration pipelines without a graphical display. The runner boots the simulation, monitors the virtual UART logs, and exits with code `0` on success or code `1` on timeout/failure. + +* **Windows (PowerShell)**: ```powershell - .\scripts\simulate.ps1 + powershell -ExecutionPolicy Bypass -File .\scripts\test_headless.ps1 ``` -* **On Linux / macOS (Bash)**: +* **Linux / macOS (Bash)**: ```bash - chmod +x ./scripts/simulate.sh - ./scripts/simulate.sh + chmod +x ./scripts/test_headless.sh + ./scripts/test_headless.sh ``` +Test any specific demo headlessly: +```powershell +powershell -ExecutionPolicy Bypass -File .\scripts\test_headless.ps1 -Demo threadx_basic -TimeoutSeconds 8 +``` + --- -## Hardware Verification Status +## Physical Board Deployment & Flashing > [!NOTE] -> This Board Support Package is developed and validated using **Antmicro Renode simulation**. Physical hardware verification on the EVK-MIMXRT1064 evaluation board is welcome and encouraged! +> *Simulated in Renode, Pending Physical Hardware Verification* + +When flashing to physical hardware, ensure the EVK board boot mode switches (`SW7`: `1-OFF, 2-ON, 3-OFF, 4-ON`) are configured for **Internal Boot (FlexSPI NOR Flash)**. Connect your PC to the OpenSDA USB port (`J41`). + +### Flashing Method 1: OpenSDA Drag-and-Drop (DAP-Link) +1. Connect the EVK board to your PC via micro-USB connector `J41`. +2. The onboard OpenSDA circuit mounts as a USB mass storage drive (e.g., `RT1064-EVK`). +3. Copy `build/app/demos//mimxrt1064_threadx.bin` and paste it directly into the `RT1064-EVK` drive. +4. The OpenSDA LED blinks rapidly during programming. Once complete, press the `SW3` (RESET) button to boot. + +### Flashing Method 2: SEGGER J-Link +If using a SEGGER J-Link probe (or OpenSDA programmed with J-Link firmware): +1. Connect via J-Link Commander: + ```text + JLink.exe -device MIMXRT1064xxx6A -if SWD -speed 4000 -autoconnect 1 + ``` +2. Flash the raw binary or hex file: + ```text + loadfile build/app/demos//mimxrt1064_threadx.hex + r + g + ``` + +### Flashing Method 3: pyOCD Command Line +Using the open-source pyOCD programmer: +1. Install pyOCD and the NXP device pack: + ```bash + pip install pyocd && pyocd pack install MIMXRT1064 + ``` +2. Program the target: + ```bash + pyocd flash -t mimxrt1064 build/app/demos//mimxrt1064_threadx.hex + ``` + +### Flashing Method 4: NXP MCUXpresso IDE / GUI Flash Tool +1. Open MCUXpresso IDE and select **GUI Flash Tool** from the toolbar. +2. Select target device `MIMXRT1064xxxxA` and target memory `PROGRAM_FLASH` (`0x70000000`). +3. Select `build/app/demos//mimxrt1064_threadx.elf` (or `.bin`) and click **Program**. + +--- + +## Developer Guide: How to Add a New Demo + +The decoupled architecture of `board_bsp` makes adding custom applications straightforward: + +### Step 1: Create the Demo Directory +Create a folder under `app/demos/` (e.g., `app/demos/my_new_demo/`). + +### Step 2: Write Application Code +Create `main.c` utilizing the clean BSP initialization API: +```c +#include "board_init.h" +#include "console.h" +#include "tx_api.h" + +int main(void) +{ + /* Initialize MPU, 600 MHz system clocks, and GPIO pins */ + board_init(); + + /* Initialize LPUART1 serial console */ + console_init(); + + /* Optional: Initialize Ethernet MAC/PHY if using networking */ + // board_ethernet_init(); + + /* Enter ThreadX RTOS Kernel */ + tx_kernel_enter(); + return 0; +} +``` + +### Step 3: Create `CMakeLists.txt` +In your demo directory: +```cmake +set(DEMO_TARGET "demo_my_new_demo") +add_executable(${DEMO_TARGET} + main.c +) +set_target_properties(${DEMO_TARGET} PROPERTIES OUTPUT_NAME "mimxrt1064_threadx") + +target_include_directories(${DEMO_TARGET} PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/../.. +) + +target_link_libraries(${DEMO_TARGET} PRIVATE + board_bsp + threadx + # netxduo # Uncomment if using network + # netx_imxrt_driver # Uncomment if using network +) + +set_target_linker(${DEMO_TARGET} "${CMAKE_CURRENT_SOURCE_DIR}/../../startup/MIMXRT1064xxxxx_flexspi_nor.ld") +post_build(${DEMO_TARGET}) +``` + +### Step 4: Build and Simulate +```bash +cmake -DACTIVE_DEMO=my_new_demo -B build -G Ninja +cmake --build build +``` diff --git a/NXP/MIMXRT1064-EVK/app/MIMXRT1062.h b/NXP/MIMXRT1064-EVK/app/MIMXRT1062.h index 5c20680c..fcfe2f66 100644 --- a/NXP/MIMXRT1064-EVK/app/MIMXRT1062.h +++ b/NXP/MIMXRT1064-EVK/app/MIMXRT1062.h @@ -1,3 +1,16 @@ +/* + * Copyright (c) 2026 Eclipse ThreadX contributors + * + * 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. + */ + /* * Compatibility header: redirects MIMXRT1062.h from stock NetX Duo driver * to MIMXRT1064 device registers without modifying vendor source files. diff --git a/NXP/MIMXRT1064-EVK/app/demos/netx_echo/CMakeLists.txt b/NXP/MIMXRT1064-EVK/app/demos/netx_echo/CMakeLists.txt index a3a4ec5c..9aa97bf7 100644 --- a/NXP/MIMXRT1064-EVK/app/demos/netx_echo/CMakeLists.txt +++ b/NXP/MIMXRT1064-EVK/app/demos/netx_echo/CMakeLists.txt @@ -10,12 +10,14 @@ # Ali Eissa - 2026 version. # Server Executable Target (mimxrt1064_threadx) -add_executable(${PROJECT_NAME} +set(SERVER_TARGET "demo_netx_echo_server") +add_executable(${SERVER_TARGET} main.c ) +set_target_properties(${SERVER_TARGET} PROPERTIES OUTPUT_NAME "mimxrt1064_threadx") # Set compile definitions for server -target_compile_definitions(${PROJECT_NAME} +target_compile_definitions(${SERVER_TARGET} PRIVATE CPU_MIMXRT1064DVL6A XIP_EXTERNAL_FLASH=1 @@ -28,7 +30,7 @@ target_compile_definitions(${PROJECT_NAME} ) # Include paths for server -target_include_directories(${PROJECT_NAME} +target_include_directories(${SERVER_TARGET} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/../.. @@ -44,7 +46,7 @@ target_include_directories(${PROJECT_NAME} ) # Link libraries for server -target_link_libraries(${PROJECT_NAME} +target_link_libraries(${SERVER_TARGET} PRIVATE board_bsp threadx @@ -54,14 +56,15 @@ target_link_libraries(${PROJECT_NAME} ) # Apply GCC linker script and post-build outputs for server -set_target_linker(${PROJECT_NAME} "${CMAKE_CURRENT_SOURCE_DIR}/../../startup/MIMXRT1064xxxxx_flexspi_nor.ld") -post_build(${PROJECT_NAME}) +set_target_linker(${SERVER_TARGET} "${CMAKE_CURRENT_SOURCE_DIR}/../../startup/MIMXRT1064xxxxx_flexspi_nor.ld") +post_build(${SERVER_TARGET}) # Automated Verification Client Executable Target (mimxrt1064_client) -set(CLIENT_TARGET "mimxrt1064_client") +set(CLIENT_TARGET "demo_netx_echo_client") add_executable(${CLIENT_TARGET} client_main.c ) +set_target_properties(${CLIENT_TARGET} PROPERTIES OUTPUT_NAME "mimxrt1064_client") # Set compile definitions for client target_compile_definitions(${CLIENT_TARGET} diff --git a/NXP/MIMXRT1064-EVK/app/demos/netx_trng_console/CMakeLists.txt b/NXP/MIMXRT1064-EVK/app/demos/netx_trng_console/CMakeLists.txt index a3a4ec5c..d8fc8cab 100644 --- a/NXP/MIMXRT1064-EVK/app/demos/netx_trng_console/CMakeLists.txt +++ b/NXP/MIMXRT1064-EVK/app/demos/netx_trng_console/CMakeLists.txt @@ -10,12 +10,14 @@ # Ali Eissa - 2026 version. # Server Executable Target (mimxrt1064_threadx) -add_executable(${PROJECT_NAME} +set(SERVER_TARGET "demo_netx_trng_server") +add_executable(${SERVER_TARGET} main.c ) +set_target_properties(${SERVER_TARGET} PROPERTIES OUTPUT_NAME "mimxrt1064_threadx") # Set compile definitions for server -target_compile_definitions(${PROJECT_NAME} +target_compile_definitions(${SERVER_TARGET} PRIVATE CPU_MIMXRT1064DVL6A XIP_EXTERNAL_FLASH=1 @@ -28,7 +30,7 @@ target_compile_definitions(${PROJECT_NAME} ) # Include paths for server -target_include_directories(${PROJECT_NAME} +target_include_directories(${SERVER_TARGET} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/../.. @@ -44,7 +46,7 @@ target_include_directories(${PROJECT_NAME} ) # Link libraries for server -target_link_libraries(${PROJECT_NAME} +target_link_libraries(${SERVER_TARGET} PRIVATE board_bsp threadx @@ -54,14 +56,15 @@ target_link_libraries(${PROJECT_NAME} ) # Apply GCC linker script and post-build outputs for server -set_target_linker(${PROJECT_NAME} "${CMAKE_CURRENT_SOURCE_DIR}/../../startup/MIMXRT1064xxxxx_flexspi_nor.ld") -post_build(${PROJECT_NAME}) +set_target_linker(${SERVER_TARGET} "${CMAKE_CURRENT_SOURCE_DIR}/../../startup/MIMXRT1064xxxxx_flexspi_nor.ld") +post_build(${SERVER_TARGET}) # Automated Verification Client Executable Target (mimxrt1064_client) -set(CLIENT_TARGET "mimxrt1064_client") +set(CLIENT_TARGET "demo_netx_trng_client") add_executable(${CLIENT_TARGET} client_main.c ) +set_target_properties(${CLIENT_TARGET} PROPERTIES OUTPUT_NAME "mimxrt1064_client") # Set compile definitions for client target_compile_definitions(${CLIENT_TARGET} diff --git a/NXP/MIMXRT1064-EVK/app/demos/netx_trng_console/nx_user.h b/NXP/MIMXRT1064-EVK/app/demos/netx_trng_console/nx_user.h deleted file mode 100644 index eccf436a..00000000 --- a/NXP/MIMXRT1064-EVK/app/demos/netx_trng_console/nx_user.h +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright (c) 2026 Eclipse ThreadX contributors - * - * 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. - */ - -#ifndef NX_USER_H -#define NX_USER_H - -#define NX_DISABLE_IPV6 -#define NX_PHYSICAL_HEADER 16 -#define NX_ENABLE_EXTENDED_NOTIFY_SUPPORT - -#endif /* NX_USER_H */ diff --git a/NXP/MIMXRT1064-EVK/app/demos/threadx_basic/CMakeLists.txt b/NXP/MIMXRT1064-EVK/app/demos/threadx_basic/CMakeLists.txt index 41f8f3bb..b8431811 100644 --- a/NXP/MIMXRT1064-EVK/app/demos/threadx_basic/CMakeLists.txt +++ b/NXP/MIMXRT1064-EVK/app/demos/threadx_basic/CMakeLists.txt @@ -9,12 +9,14 @@ # Contributors: # Ali Eissa - 2026 version. -add_executable(${PROJECT_NAME} +set(DEMO_TARGET "demo_threadx_basic") +add_executable(${DEMO_TARGET} main.c ) +set_target_properties(${DEMO_TARGET} PROPERTIES OUTPUT_NAME "mimxrt1064_threadx") # Set compile definitions for our executable -target_compile_definitions(${PROJECT_NAME} +target_compile_definitions(${DEMO_TARGET} PRIVATE CPU_MIMXRT1064DVL6A XIP_EXTERNAL_FLASH=1 @@ -27,7 +29,7 @@ target_compile_definitions(${PROJECT_NAME} ) # Include paths for the executable target -target_include_directories(${PROJECT_NAME} +target_include_directories(${DEMO_TARGET} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/../.. @@ -41,7 +43,7 @@ target_include_directories(${PROJECT_NAME} ) # Link libraries -target_link_libraries(${PROJECT_NAME} +target_link_libraries(${DEMO_TARGET} PRIVATE board_bsp threadx @@ -49,7 +51,7 @@ target_link_libraries(${PROJECT_NAME} ) # Apply GCC linker script and print memory usage (utilities.cmake function) -set_target_linker(${PROJECT_NAME} "${CMAKE_CURRENT_SOURCE_DIR}/../../startup/MIMXRT1064xxxxx_flexspi_nor.ld") +set_target_linker(${DEMO_TARGET} "${CMAKE_CURRENT_SOURCE_DIR}/../../startup/MIMXRT1064xxxxx_flexspi_nor.ld") # Post-build commands to generate raw .bin and .hex files -post_build(${PROJECT_NAME}) +post_build(${DEMO_TARGET}) diff --git a/NXP/MIMXRT1064-EVK/app/demos/threadx_basic/main.c b/NXP/MIMXRT1064-EVK/app/demos/threadx_basic/main.c index b313f404..6ff1132d 100644 --- a/NXP/MIMXRT1064-EVK/app/demos/threadx_basic/main.c +++ b/NXP/MIMXRT1064-EVK/app/demos/threadx_basic/main.c @@ -8,7 +8,7 @@ * SPDX-License-Identifier: MIT * * Contributors: - * Ali Eissa - 2026 NXP i.MX RT1064 port. + * Ali Eissa - 2026 version. */ #include "board_init.h" diff --git a/NXP/MIMXRT1064-EVK/app/startup/MIMXRT1064xxxxx_flexspi_nor.ld b/NXP/MIMXRT1064-EVK/app/startup/MIMXRT1064xxxxx_flexspi_nor.ld index 8e79f28c..9fd0ae83 100644 --- a/NXP/MIMXRT1064-EVK/app/startup/MIMXRT1064xxxxx_flexspi_nor.ld +++ b/NXP/MIMXRT1064-EVK/app/startup/MIMXRT1064xxxxx_flexspi_nor.ld @@ -27,6 +27,10 @@ ** ################################################################### */ +/* +** Adapted memory sections for Eclipse ThreadX RTOS by Eclipse ThreadX contributors. +*/ + /* Entry Point */ ENTRY(Reset_Handler) diff --git a/NXP/MIMXRT1064-EVK/app/startup/tx_initialize_low_level.S b/NXP/MIMXRT1064-EVK/app/startup/tx_initialize_low_level.S index 40e3879d..d34654b5 100644 --- a/NXP/MIMXRT1064-EVK/app/startup/tx_initialize_low_level.S +++ b/NXP/MIMXRT1064-EVK/app/startup/tx_initialize_low_level.S @@ -9,7 +9,7 @@ * SPDX-License-Identifier: MIT * * Contributors: - * Ali Eissa - 2026 NXP i.MX RT1064 port. + * Ali Eissa - 2026 version. **************************************************************************/ /**************************************************************************/ diff --git a/NXP/MIMXRT1064-EVK/cmake/utilities.cmake b/NXP/MIMXRT1064-EVK/cmake/utilities.cmake index d584424d..0cc921f9 100644 --- a/NXP/MIMXRT1064-EVK/cmake/utilities.cmake +++ b/NXP/MIMXRT1064-EVK/cmake/utilities.cmake @@ -14,14 +14,14 @@ function(post_build TARGET) if(CMAKE_C_COMPILER_ID STREQUAL "IAR") - add_custom_target(${TARGET}.bin ALL + add_custom_target(${TARGET}_bin ALL DEPENDS ${TARGET} COMMAND ${CMAKE_IAR_ELFTOOL} --bin ${TARGET}.elf ${TARGET}.bin) elseif(CMAKE_C_COMPILER_ID STREQUAL "GNU") - add_custom_target(${TARGET}.bin ALL + add_custom_target(${TARGET}_bin ALL DEPENDS ${TARGET} - COMMAND ${CMAKE_OBJCOPY} -Obinary $ $/${TARGET}.bin - COMMAND ${CMAKE_OBJCOPY} -Oihex $ $/${TARGET}.hex) + COMMAND ${CMAKE_OBJCOPY} -Obinary $ $/$.bin + COMMAND ${CMAKE_OBJCOPY} -Oihex $ $/$.hex) else() message(FATAL_ERROR "Unknown CMAKE_C_COMPILER_ID ${CMAKE_C_COMPILER_ID}") endif() @@ -33,7 +33,7 @@ function(set_target_linker TARGET LINKER_SCRIPT) target_link_options(${TARGET} PRIVATE --map=${TARGET}.map) elseif(CMAKE_C_COMPILER_ID STREQUAL "GNU") target_link_options(${TARGET} PRIVATE -T${LINKER_SCRIPT}) - target_link_options(${TARGET} PRIVATE -Wl,-Map=${TARGET}.map) + target_link_options(${TARGET} PRIVATE -Wl,-Map=$/$.map) set_target_properties(${TARGET} PROPERTIES SUFFIX ".elf") else() message(FATAL_ERROR "Unknown CMAKE_C_COMPILER_ID ${CMAKE_C_COMPILER_ID}") diff --git a/NXP/MIMXRT1064-EVK/app/demos/netx_echo/nx_user.h b/NXP/MIMXRT1064-EVK/lib/netxduo/nx_user.h similarity index 100% rename from NXP/MIMXRT1064-EVK/app/demos/netx_echo/nx_user.h rename to NXP/MIMXRT1064-EVK/lib/netxduo/nx_user.h diff --git a/NXP/MIMXRT1064-EVK/renode/mimxrt1064-evk.resc b/NXP/MIMXRT1064-EVK/renode/mimxrt1064-evk.resc index 6ba323b0..ed38157e 100644 --- a/NXP/MIMXRT1064-EVK/renode/mimxrt1064-evk.resc +++ b/NXP/MIMXRT1064-EVK/renode/mimxrt1064-evk.resc @@ -1,3 +1,14 @@ +# Copyright (c) 2026 Eclipse ThreadX contributors +# +# 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. + :name: MIMXRT1064-EVK ThreadX Demo :description: This script runs the Eclipse ThreadX & NetX Duo demo on NXP i.MX RT1064-EVK. diff --git a/NXP/MIMXRT1064-EVK/renode/mimxrt1064-headless-multinode.resc b/NXP/MIMXRT1064-EVK/renode/mimxrt1064-headless-multinode.resc new file mode 100644 index 00000000..4f695be6 --- /dev/null +++ b/NXP/MIMXRT1064-EVK/renode/mimxrt1064-headless-multinode.resc @@ -0,0 +1,43 @@ +# Copyright (c) 2026 Eclipse ThreadX contributors +# +# 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. + +:name: MIMXRT1064-EVK Headless Multi-Node CI Test +:description: Headless two-node verification connecting server and client via virtual switch. + +# 1. Create Virtual Ethernet Switch +emulation CreateSwitch "switch" + +# 2. Server Machine (192.168.0.100) +mach create "server" +machine LoadPlatformDescription $ORIGIN/mimxrt1064-evk.repl +connector Connect sysbus.enet switch +sysbus.lpuart1 CreateFileBackend $ORIGIN/../build/server_uart.log true + +$bin_server?=$ORIGIN/../build/mimxrt1064_threadx.elf +cpu VectorTableOffset 0x70002000 +sysbus LoadELF $bin_server +cpu PC `sysbus ReadDoubleWord 0x70002004` +cpu SP `sysbus ReadDoubleWord 0x70002000` + +# 3. Client Machine (192.168.0.101) +mach create "client" +machine LoadPlatformDescription $ORIGIN/mimxrt1064-evk.repl +connector Connect sysbus.enet switch +sysbus.lpuart1 CreateFileBackend $ORIGIN/../build/client_uart.log true + +$bin_client?=$ORIGIN/../build/mimxrt1064_client.elf +cpu VectorTableOffset 0x70002000 +sysbus LoadELF $bin_client +cpu PC `sysbus ReadDoubleWord 0x70002004` +cpu SP `sysbus ReadDoubleWord 0x70002000` + +# 4. Start Simulation +start diff --git a/NXP/MIMXRT1064-EVK/renode/mimxrt1064-headless-single.resc b/NXP/MIMXRT1064-EVK/renode/mimxrt1064-headless-single.resc new file mode 100644 index 00000000..7e4f74bd --- /dev/null +++ b/NXP/MIMXRT1064-EVK/renode/mimxrt1064-headless-single.resc @@ -0,0 +1,26 @@ +# Copyright (c) 2026 Eclipse ThreadX contributors +# +# 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. + +:name: MIMXRT1064-EVK Headless Single-Node CI Test +:description: Headless single-node verification capturing LPUART1 output to log file. + +mach create "mimxrt1064-evk" +machine LoadPlatformDescription $ORIGIN/mimxrt1064-evk.repl + +sysbus.lpuart1 CreateFileBackend $ORIGIN/../build/server_uart.log true + +$bin?=$ORIGIN/../build/mimxrt1064_threadx.elf +cpu VectorTableOffset 0x70002000 +sysbus LoadELF $bin +cpu PC `sysbus ReadDoubleWord 0x70002004` +cpu SP `sysbus ReadDoubleWord 0x70002000` + +start diff --git a/NXP/MIMXRT1064-EVK/renode/mimxrt1064-network-multinode.resc b/NXP/MIMXRT1064-EVK/renode/mimxrt1064-network-multinode.resc index 88be9668..54343a1b 100644 --- a/NXP/MIMXRT1064-EVK/renode/mimxrt1064-network-multinode.resc +++ b/NXP/MIMXRT1064-EVK/renode/mimxrt1064-network-multinode.resc @@ -1,3 +1,14 @@ +# Copyright (c) 2026 Eclipse ThreadX contributors +# +# 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. + :name: MIMXRT1064-EVK NetX Duo Two-Node Virtual Network Verification :description: This script creates two MIMXRT1064-EVK nodes connected via a virtual Ethernet switch: : - "server": Echo Server on 192.168.0.100 (ICMP Ping, UDP port 7, TCP port 7) diff --git a/NXP/MIMXRT1064-EVK/renode/mimxrt1064-trng-console.resc b/NXP/MIMXRT1064-EVK/renode/mimxrt1064-trng-console.resc index ca877e09..58f2465a 100644 --- a/NXP/MIMXRT1064-EVK/renode/mimxrt1064-trng-console.resc +++ b/NXP/MIMXRT1064-EVK/renode/mimxrt1064-trng-console.resc @@ -1,3 +1,14 @@ +# Copyright (c) 2026 Eclipse ThreadX contributors +# +# 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. + :name: MIMXRT1064-EVK Hardware TRNG & Console Two-Node Verification :description: This script creates two MIMXRT1064-EVK nodes connected via a virtual Ethernet switch: : - "server": TRNG Console Server on 192.168.0.100 (TCP Port 23, ICMP Ping) diff --git a/NXP/MIMXRT1064-EVK/scripts/build.ps1 b/NXP/MIMXRT1064-EVK/scripts/build.ps1 index a0cd9c99..b785894f 100644 --- a/NXP/MIMXRT1064-EVK/scripts/build.ps1 +++ b/NXP/MIMXRT1064-EVK/scripts/build.ps1 @@ -12,7 +12,7 @@ param( [switch]$Clean, [switch]$Rebuild, - [string]$Demo = "netx_echo" + [string]$Demo = "all" ) $BoardDir = Resolve-Path "$PSScriptRoot/.." @@ -85,13 +85,29 @@ if ($LASTEXITCODE -ne 0) { Write-Host "" Write-Host "[SUCCESS] Build finished successfully!" -ForegroundColor Green -Write-Host "Server Firmware ELF: $(Join-Path $BUILD_DIR 'mimxrt1064_threadx.elf')" -Write-Host "Server Firmware BIN: $(Join-Path $BUILD_DIR 'mimxrt1064_threadx.bin')" -Write-Host "Server Firmware HEX: $(Join-Path $BUILD_DIR 'mimxrt1064_threadx.hex')" -if (Test-Path (Join-Path $BUILD_DIR 'mimxrt1064_client.elf')) { - Write-Host "Client Firmware ELF: $(Join-Path $BUILD_DIR 'mimxrt1064_client.elf')" - Write-Host "Client Firmware BIN: $(Join-Path $BUILD_DIR 'mimxrt1064_client.bin')" - Write-Host "Client Firmware HEX: $(Join-Path $BUILD_DIR 'mimxrt1064_client.hex')" + +$demosToReport = @() +if ($Demo -eq "all") { + $demosToReport = @("threadx_basic", "netx_echo", "netx_trng_console") +} else { + $demosToReport = @($Demo) +} + +foreach ($d in $demosToReport) { + $demoDir = Join-Path $BUILD_DIR "app/demos/$d" + if (Test-Path $demoDir) { + Write-Host "[$d] Output Binaries in $demoDir :" -ForegroundColor Cyan + $serverElf = Join-Path $demoDir "mimxrt1064_threadx.elf" + $clientElf = Join-Path $demoDir "mimxrt1064_client.elf" + if (Test-Path $serverElf) { + Write-Host " - Server ELF: $serverElf" + Write-Host " - Server BIN: $(Join-Path $demoDir 'mimxrt1064_threadx.bin')" + } + if (Test-Path $clientElf) { + Write-Host " - Client ELF: $clientElf" + Write-Host " - Client BIN: $(Join-Path $demoDir 'mimxrt1064_client.bin')" + } + } } Pop-Location diff --git a/NXP/MIMXRT1064-EVK/scripts/build.sh b/NXP/MIMXRT1064-EVK/scripts/build.sh index 48d5327e..101ac40f 100644 --- a/NXP/MIMXRT1064-EVK/scripts/build.sh +++ b/NXP/MIMXRT1064-EVK/scripts/build.sh @@ -19,14 +19,14 @@ NUM_JOBS=4 CLEAN=0 REBUILD=0 -DEMO="netx_echo" +DEMO="all" # Parse arguments while [[ "$#" -gt 0 ]]; do case $1 in --clean) CLEAN=1 ;; --rebuild) REBUILD=1 ;; - --demo) DEMO="$2"; shift ;; + -d|--demo) DEMO="$2"; shift ;; *) echo "Unknown parameter passed: $1"; exit 1 ;; esac shift @@ -84,11 +84,24 @@ ninja -j ${NUM_JOBS} echo "" echo "[SUCCESS] Build finished successfully!" -echo "Server Firmware ELF: ${BUILD_DIR}/mimxrt1064_threadx.elf" -echo "Server Firmware BIN: ${BUILD_DIR}/mimxrt1064_threadx.bin" -echo "Server Firmware HEX: ${BUILD_DIR}/mimxrt1064_threadx.hex" -if [ -f "${BUILD_DIR}/mimxrt1064_client.elf" ]; then - echo "Client Firmware ELF: ${BUILD_DIR}/mimxrt1064_client.elf" - echo "Client Firmware BIN: ${BUILD_DIR}/mimxrt1064_client.bin" - echo "Client Firmware HEX: ${BUILD_DIR}/mimxrt1064_client.hex" + +if [ "${DEMO}" = "all" ]; then + DEMOS_TO_REPORT=("threadx_basic" "netx_echo" "netx_trng_console") +else + DEMOS_TO_REPORT=("${DEMO}") fi + +for d in "${DEMOS_TO_REPORT[@]}"; do + DEMO_DIR="${BUILD_DIR}/app/demos/${d}" + if [ -d "${DEMO_DIR}" ]; then + echo "[${d}] Output Binaries in ${DEMO_DIR}:" + if [ -f "${DEMO_DIR}/mimxrt1064_threadx.elf" ]; then + echo " - Server ELF: ${DEMO_DIR}/mimxrt1064_threadx.elf" + echo " - Server BIN: ${DEMO_DIR}/mimxrt1064_threadx.bin" + fi + if [ -f "${DEMO_DIR}/mimxrt1064_client.elf" ]; then + echo " - Client ELF: ${DEMO_DIR}/mimxrt1064_client.elf" + echo " - Client BIN: ${DEMO_DIR}/mimxrt1064_client.bin" + fi + fi +done diff --git a/NXP/MIMXRT1064-EVK/scripts/fetch_sdk.ps1 b/NXP/MIMXRT1064-EVK/scripts/fetch_sdk.ps1 index 76d585a7..b99f9637 100644 --- a/NXP/MIMXRT1064-EVK/scripts/fetch_sdk.ps1 +++ b/NXP/MIMXRT1064-EVK/scripts/fetch_sdk.ps1 @@ -186,7 +186,7 @@ try { # 3. Fetch CMSIS Core headers (standard ARM CMSIS-Core include files) Write-Host "[INFO] Cloning CMSIS Core headers (depth=1)..." $cmsisCloneDir = Join-Path $TempDir "cmsis_core_repo" - git clone --depth 1 https://github.com/STMicroelectronics/cmsis-core.git $cmsisCloneDir + git clone --depth 1 https://github.com/ARM-software/CMSIS_5.git $cmsisCloneDir if ($LASTEXITCODE -ne 0) { throw "Failed to clone CMSIS Core repository" } diff --git a/NXP/MIMXRT1064-EVK/scripts/fetch_sdk.sh b/NXP/MIMXRT1064-EVK/scripts/fetch_sdk.sh index c89fa6df..0f2e9b07 100644 --- a/NXP/MIMXRT1064-EVK/scripts/fetch_sdk.sh +++ b/NXP/MIMXRT1064-EVK/scripts/fetch_sdk.sh @@ -128,7 +128,7 @@ echo "" # 3. Fetch CMSIS Core headers echo "[INFO] Cloning CMSIS Core headers (depth=1)..." CMSIS_CLONE_DIR="${TEMP_DIR}/cmsis_core_repo" -git clone --depth 1 https://github.com/STMicroelectronics/cmsis-core.git "${CMSIS_CLONE_DIR}" +git clone --depth 1 https://github.com/ARM-software/CMSIS_5.git "${CMSIS_CLONE_DIR}" cp -r "${CMSIS_CLONE_DIR}/CMSIS/Core/Include/"* "${CMSIS_INCLUDE_DEST}/" echo "[OK] CMSIS Core headers copied" echo "" diff --git a/NXP/MIMXRT1064-EVK/scripts/simulate.ps1 b/NXP/MIMXRT1064-EVK/scripts/simulate.ps1 index 842c5de4..716f56db 100644 --- a/NXP/MIMXRT1064-EVK/scripts/simulate.ps1 +++ b/NXP/MIMXRT1064-EVK/scripts/simulate.ps1 @@ -10,47 +10,83 @@ # Ali Eissa - 2026 version. param( - [string]$Resc + [Alias("d")] + [string]$Demo, + [string]$Resc, + [Nullable[int]]$Seed ) $BoardDir = Resolve-Path "$PSScriptRoot/.." -$ServerElf = Join-Path $BoardDir "build/mimxrt1064_threadx.elf" -$ClientElf = Join-Path $BoardDir "build/mimxrt1064_client.elf" +$BuildDir = Join-Path $BoardDir "build" -if (-not (Test-Path $ServerElf)) { - Write-Error "Binary $ServerElf not found. Please build the project first using .\scripts\build.ps1" - exit 1 +# 1. Resolve which demo to simulate +$selectedDemo = $Demo +if (-not $selectedDemo) { + # Check CMakeCache.txt for ACTIVE_DEMO + $cacheFile = Join-Path $BuildDir "CMakeCache.txt" + if (Test-Path $cacheFile) { + $match = Select-String -Path $cacheFile -Pattern "^ACTIVE_DEMO:STRING=(.*)$" + if ($match) { + $cached = $match.Matches.Groups[1].Value.Trim() + if ($cached -and $cached -ne "all") { + $selectedDemo = $cached + } + } + } } -# Determine RESC script: custom argument, or auto-detect based on cached demo -$cachedDemo = "" -$cacheFile = Join-Path $BoardDir "build/CMakeCache.txt" -if (Test-Path $cacheFile) { - $match = Select-String -Path $cacheFile -Pattern "^ACTIVE_DEMO:STRING=(.*)$" - if ($match) { - $cachedDemo = $match.Matches.Groups[1].Value.Trim() +# If still undetermined, check existing built demo directories or default to threadx_basic +if (-not $selectedDemo) { + if (Test-Path (Join-Path $BuildDir "app/demos/threadx_basic/mimxrt1064_threadx.elf")) { + $selectedDemo = "threadx_basic" + } elseif (Test-Path (Join-Path $BuildDir "app/demos/netx_echo/mimxrt1064_threadx.elf")) { + $selectedDemo = "netx_echo" + } elseif (Test-Path (Join-Path $BuildDir "app/demos/netx_trng_console/mimxrt1064_threadx.elf")) { + $selectedDemo = "netx_trng_console" + } else { + $selectedDemo = "threadx_basic" } } +# 2. Locate firmware binaries for the selected demo +$serverElfRel = "build/app/demos/$selectedDemo/mimxrt1064_threadx.elf" +$clientElfRel = "build/app/demos/$selectedDemo/mimxrt1064_client.elf" + +# Fallback to root build dir if per-demo subfolder does not exist +if (-not (Test-Path (Join-Path $BoardDir $serverElfRel)) -and (Test-Path (Join-Path $BoardDir "build/mimxrt1064_threadx.elf"))) { + $serverElfRel = "build/mimxrt1064_threadx.elf" + $clientElfRel = "build/mimxrt1064_client.elf" +} + +$ServerElf = Join-Path $BoardDir $serverElfRel +$ClientElf = Join-Path $BoardDir $clientElfRel + +if (-not (Test-Path $ServerElf)) { + Write-Host "[ERROR] Firmware binary for demo '$selectedDemo' not found at:" -ForegroundColor Red + Write-Host " $ServerElf" -ForegroundColor Red + Write-Host "" + Write-Host "Please build the demo first using:" -ForegroundColor Yellow + Write-Host " .\scripts\build.ps1 -Demo $selectedDemo" -ForegroundColor Yellow + exit 1 +} + +# 3. Select Renode script and verification mode if ($Resc) { $RescRelPath = $Resc - $Mode = "Custom Script" -} elseif ($cachedDemo -eq "netx_trng_console") { + $Mode = "Custom Script ($Resc)" +} elseif ($selectedDemo -eq "netx_trng_console") { $RescRelPath = "renode/mimxrt1064-trng-console.resc" $Mode = "Hardware TRNG Console (Server: 192.168.0.100, Client: 192.168.0.101)" -} elseif ($cachedDemo -eq "netx_echo") { +} elseif ($selectedDemo -eq "netx_echo") { $RescRelPath = "renode/mimxrt1064-network-multinode.resc" - $Mode = "Multi-Node Network Echo Verification (Server: 192.168.0.100, Client: 192.168.0.101)" -} elseif (Test-Path $ClientElf) { - $RescRelPath = "renode/mimxrt1064-network-multinode.resc" - $Mode = "Multi-Node Network Verification (Server: 192.168.0.100, Client: 192.168.0.101)" + $Mode = "Multi-Node Network Echo (Server: 192.168.0.100, Client: 192.168.0.101)" } else { $RescRelPath = "renode/mimxrt1064-evk.resc" - $Mode = "Single-Node Demo" + $Mode = "ThreadX Core Basic Demo (Single-Node)" } $RescFullPath = Join-Path $BoardDir $RescRelPath -# Find Renode executable +# 4. Find Renode executable $RenodeExe = (Get-Command renode -ErrorAction SilentlyContinue).Source if (-not $RenodeExe -and (Test-Path "C:\Program Files\Renode\renode.exe")) { $RenodeExe = "C:\Program Files\Renode\renode.exe" @@ -64,12 +100,16 @@ if (-not $RenodeExe) { Write-Host "==========================================" Write-Host "Starting Renode Simulation" Write-Host "==========================================" -Write-Host "Renode: $RenodeExe" -Write-Host "Mode: $Mode" -Write-Host "Script: $RescFullPath" -Write-Host "Server ELF: $ServerElf" +Write-Host "Renode: $RenodeExe" +Write-Host "Demo: $selectedDemo" +Write-Host "Mode: $Mode" +Write-Host "Script: $RescFullPath" +if ($null -ne $Seed) { + Write-Host "Seed: $Seed (Deterministic)" +} +Write-Host "Server ELF: $ServerElf" if (Test-Path $ClientElf) { - Write-Host "Client ELF: $ClientElf" + Write-Host "Client ELF: $ClientElf" } Write-Host "" Write-Host "Opening Renode Monitor and LPUART1 terminal analyzer(s)..." @@ -78,5 +118,16 @@ Write-Host "==========================================" Set-Location $BoardDir +# 5. Build Renode execution command passing clean relative binary paths +$renodeCmd = "" +if ($null -ne $Seed) { + $renodeCmd += "emulation SetSeed $Seed; " +} +$renodeCmd += "`$bin = @`"$serverElfRel`"; `$bin_server = @`"$serverElfRel`"; " +if (Test-Path $ClientElf) { + $renodeCmd += "`$bin_client = @`"$clientElfRel`"; " +} +$renodeCmd += "include @`"$RescRelPath`"" + # Pass relative script path with quotes to avoid tokenization errors when workspace contains spaces -& $RenodeExe -e "include @`"$RescRelPath`"" +& $RenodeExe -e "$renodeCmd" diff --git a/NXP/MIMXRT1064-EVK/scripts/simulate.sh b/NXP/MIMXRT1064-EVK/scripts/simulate.sh index dcf574be..d3d3cdf1 100644 --- a/NXP/MIMXRT1064-EVK/scripts/simulate.sh +++ b/NXP/MIMXRT1064-EVK/scripts/simulate.sh @@ -14,36 +14,95 @@ set -e SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" BOARD_DIR="$(cd "${SCRIPT_DIR}/.." && pwd)" -SERVER_ELF="${BOARD_DIR}/build/mimxrt1064_threadx.elf" -CLIENT_ELF="${BOARD_DIR}/build/mimxrt1064_client.elf" +BUILD_DIR="${BOARD_DIR}/build" -if [ ! -f "${SERVER_ELF}" ]; then - echo "[ERROR] Binary ${SERVER_ELF} not found. Please build first using ./scripts/build.sh" - exit 1 +DEMO_ARG="" +RESC_ARG="" +SEED_ARG="" + +while [[ $# -gt 0 ]]; do + case $1 in + -d|--demo) + DEMO_ARG="$2" + shift 2 + ;; + -s|--seed) + SEED_ARG="$2" + shift 2 + ;; + -r|--resc) + RESC_ARG="$2" + shift 2 + ;; + *) + if [ -z "${RESC_ARG}" ] && [[ "$1" == *.resc ]]; then + RESC_ARG="$1" + else + echo "Unknown parameter: $1" + exit 1 + fi + shift + ;; + esac +done + +# 1. Resolve which demo to simulate +SELECTED_DEMO="${DEMO_ARG}" +if [ -z "${SELECTED_DEMO}" ] && [ -f "${BUILD_DIR}/CMakeCache.txt" ]; then + CACHED_DEMO=$(grep -E "^ACTIVE_DEMO:STRING=" "${BUILD_DIR}/CMakeCache.txt" | cut -d'=' -f2 | tr -d ' \r\n') + if [ -n "${CACHED_DEMO}" ] && [ "${CACHED_DEMO}" != "all" ]; then + SELECTED_DEMO="${CACHED_DEMO}" + fi fi -CACHED_DEMO="" -if [ -f "${BOARD_DIR}/build/CMakeCache.txt" ]; then - CACHED_DEMO=$(grep -E "^ACTIVE_DEMO:STRING=" "${BOARD_DIR}/build/CMakeCache.txt" | cut -d'=' -f2 | tr -d ' \r\n') +if [ -z "${SELECTED_DEMO}" ]; then + if [ -f "${BUILD_DIR}/app/demos/threadx_basic/mimxrt1064_threadx.elf" ]; then + SELECTED_DEMO="threadx_basic" + elif [ -f "${BUILD_DIR}/app/demos/netx_echo/mimxrt1064_threadx.elf" ]; then + SELECTED_DEMO="netx_echo" + elif [ -f "${BUILD_DIR}/app/demos/netx_trng_console/mimxrt1064_threadx.elf" ]; then + SELECTED_DEMO="netx_trng_console" + else + SELECTED_DEMO="threadx_basic" + fi fi -if [ -n "$1" ]; then - RESC_REL_PATH="$1" - MODE="Custom Script" -elif [ "$CACHED_DEMO" = "netx_trng_console" ]; then +# 2. Locate firmware binaries for the selected demo +DEMO_DIR="${BUILD_DIR}/app/demos/${SELECTED_DEMO}" +SERVER_ELF="${DEMO_DIR}/mimxrt1064_threadx.elf" +CLIENT_ELF="${DEMO_DIR}/mimxrt1064_client.elf" + +# Fallback to root build dir if per-demo subfolder does not exist +if [ ! -f "${SERVER_ELF}" ] && [ -f "${BUILD_DIR}/mimxrt1064_threadx.elf" ]; then + SERVER_ELF="${BUILD_DIR}/mimxrt1064_threadx.elf" + CLIENT_ELF="${BUILD_DIR}/mimxrt1064_client.elf" +fi + +if [ ! -f "${SERVER_ELF}" ]; then + echo "[ERROR] Firmware binary for demo '${SELECTED_DEMO}' not found at:" + echo " ${SERVER_ELF}" + echo "" + echo "Please build the demo first using:" + echo " ./scripts/build.sh -d ${SELECTED_DEMO}" + exit 1 +fi + +# 3. Select Renode script and verification mode +if [ -n "${RESC_ARG}" ]; then + RESC_REL_PATH="${RESC_ARG}" + MODE="Custom Script (${RESC_ARG})" +elif [ "$SELECTED_DEMO" = "netx_trng_console" ]; then RESC_REL_PATH="renode/mimxrt1064-trng-console.resc" MODE="Hardware TRNG Console (Server: 192.168.0.100, Client: 192.168.0.101)" -elif [ "$CACHED_DEMO" = "netx_echo" ]; then +elif [ "$SELECTED_DEMO" = "netx_echo" ]; then RESC_REL_PATH="renode/mimxrt1064-network-multinode.resc" - MODE="Multi-Node Network Echo Verification (Server: 192.168.0.100, Client: 192.168.0.101)" -elif [ -f "${CLIENT_ELF}" ]; then - RESC_REL_PATH="renode/mimxrt1064-network-multinode.resc" - MODE="Multi-Node Network Verification (Server: 192.168.0.100, Client: 192.168.0.101)" + MODE="Multi-Node Network Echo (Server: 192.168.0.100, Client: 192.168.0.101)" else RESC_REL_PATH="renode/mimxrt1064-evk.resc" - MODE="Single-Node Demo" + MODE="ThreadX Core Basic Demo (Single-Node)" fi +# 4. Find Renode executable RENODE_CMD="renode" if ! command -v renode &> /dev/null; then if [ -f "/opt/renode/renode" ]; then @@ -57,13 +116,30 @@ fi echo "==========================================" echo "Starting Renode Simulation" echo "==========================================" -echo "Mode: ${MODE}" -echo "Script: ${BOARD_DIR}/${RESC_REL_PATH}" -echo "Server ELF: ${SERVER_ELF}" +echo "Renode: ${RENODE_CMD}" +echo "Demo: ${SELECTED_DEMO}" +echo "Mode: ${MODE}" +echo "Script: ${BOARD_DIR}/${RESC_REL_PATH}" +if [ -n "${SEED_ARG}" ]; then + echo "Seed: ${SEED_ARG} (Deterministic)" +fi +echo "Server ELF: ${SERVER_ELF}" if [ -f "${CLIENT_ELF}" ]; then - echo "Client ELF: ${CLIENT_ELF}" + echo "Client ELF: ${CLIENT_ELF}" fi echo "" cd "${BOARD_DIR}" -"${RENODE_CMD}" -e "include @\"${RESC_REL_PATH}\"" + +# 5. Build Renode execution command passing explicit binary paths +RENODE_EXEC_CMD="" +if [ -n "${SEED_ARG}" ]; then + RENODE_EXEC_CMD="emulation SetSeed ${SEED_ARG}; " +fi +RENODE_EXEC_CMD="${RENODE_EXEC_CMD}\$bin = @\"${SERVER_ELF}\"; \$bin_server = @\"${SERVER_ELF}\"; " +if [ -f "${CLIENT_ELF}" ]; then + RENODE_EXEC_CMD="${RENODE_EXEC_CMD}\$bin_client = @\"${CLIENT_ELF}\"; " +fi +RENODE_EXEC_CMD="${RENODE_EXEC_CMD}include @\"${RESC_REL_PATH}\"" + +"${RENODE_CMD}" -e "${RENODE_EXEC_CMD}" diff --git a/NXP/MIMXRT1064-EVK/scripts/test_headless.ps1 b/NXP/MIMXRT1064-EVK/scripts/test_headless.ps1 new file mode 100644 index 00000000..56fb3524 --- /dev/null +++ b/NXP/MIMXRT1064-EVK/scripts/test_headless.ps1 @@ -0,0 +1,153 @@ +# Copyright (c) 2026 Eclipse ThreadX contributors +# +# 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 NXP i.MX RT1064 port. + +param( + [string]$Demo, + [int]$TimeoutSeconds = 24, + [Nullable[int]]$Seed = 12345 +) + +$BoardDir = Resolve-Path "$PSScriptRoot/.." +$BuildDir = Join-Path $BoardDir "build" + +# Optional build if Demo parameter is supplied (incremental, no clean rebuild) +if ($Demo) { + Write-Host "[INFO] Ensuring demo '$Demo' is active and built..." + & "$PSScriptRoot/build.ps1" -Demo $Demo + if ($LASTEXITCODE -ne 0) { + Write-Error "[FAIL] Build failed for demo '$Demo'" + exit 1 + } +} + +# Determine active demo +if ($Demo) { + $cachedDemo = $Demo +} else { + $cachedDemo = "netx_trng_console" + $cacheFile = Join-Path $BuildDir "CMakeCache.txt" + if (Test-Path $cacheFile) { + $match = Select-String -Path $cacheFile -Pattern "^ACTIVE_DEMO:STRING=(.*)$" + if ($match) { + $val = $match.Matches.Groups[1].Value.Trim() + if ($val -and $val -ne "all") { + $cachedDemo = $val + } + } + } +} + +$serverElfRel = "build/app/demos/$cachedDemo/mimxrt1064_threadx.elf" +$clientElfRel = "build/app/demos/$cachedDemo/mimxrt1064_client.elf" + +if (-not (Test-Path (Join-Path $BoardDir $serverElfRel)) -and (Test-Path (Join-Path $BoardDir "build/mimxrt1064_threadx.elf"))) { + $serverElfRel = "build/mimxrt1064_threadx.elf" + $clientElfRel = "build/mimxrt1064_client.elf" +} + +$ServerElf = Join-Path $BoardDir $serverElfRel +$ClientElf = Join-Path $BoardDir $clientElfRel + +if (-not (Test-Path $ServerElf)) { + Write-Error "[FAIL] Binary $ServerElf not found. Please build first using .\scripts\build.ps1 -Demo $cachedDemo" + exit 1 +} + +# Configure test mode, script, and pass marker +if ($cachedDemo -eq "threadx_basic") { + $RescRelPath = "renode/mimxrt1064-headless-single.resc" + $TargetLog = Join-Path $BuildDir "server_uart.log" + $SuccessMarker = "Executing periodic task" + $TestDescription = "ThreadX Core Basic Demo (Task Scheduling & GPIO LED)" +} else { + $RescRelPath = "renode/mimxrt1064-headless-multinode.resc" + $TargetLog = Join-Path $BuildDir "client_uart.log" + $SuccessMarker = "VERIFICATION SUCCESS" + $TestDescription = "NetX Duo Multi-Node Networking Demo ($cachedDemo)" +} + +# Find Renode executable +$RenodeExe = (Get-Command renode -ErrorAction SilentlyContinue).Source +if (-not $RenodeExe -and (Test-Path "C:\Program Files\Renode\renode.exe")) { + $RenodeExe = "C:\Program Files\Renode\renode.exe" +} +if (-not $RenodeExe) { + Write-Error "[FAIL] Renode was not found in PATH or at 'C:\Program Files\Renode\renode.exe'." + exit 1 +} + +# Remove stale log files +Remove-Item (Join-Path $BuildDir "server_uart.log") -Force -ErrorAction SilentlyContinue +Remove-Item (Join-Path $BuildDir "client_uart.log") -Force -ErrorAction SilentlyContinue + +Write-Host "==========================================" +Write-Host "Renode Headless CI Automated Test Runner" +Write-Host "==========================================" +Write-Host "Active Demo: $cachedDemo" +Write-Host "Test Suite: $TestDescription" +Write-Host "Script: $RescRelPath" +if ($null -ne $Seed) { + Write-Host "Seed: $Seed (Deterministic)" +} +Write-Host "Timeout: ${TimeoutSeconds}s" +Write-Host "Log Target: $TargetLog" +Write-Host "" +Write-Host "[INFO] Launching Renode in headless mode..." + +# Build argument list for Renode: pass explicit binary paths, include script, sleep for duration, and quit +# Build argument list for Renode: pass clean relative paths, include script, sleep for duration, and quit +$initCmd = "" +if ($null -ne $Seed) { + $initCmd += "emulation SetSeed $Seed; " +} +$initCmd += "`$bin = @`"$serverElfRel`"; `$bin_server = @`"$serverElfRel`"; " +if (Test-Path $ClientElf) { + $initCmd += "`$bin_client = @`"$clientElfRel`"; " +} +$initCmd += "include @$RescRelPath; sleep $TimeoutSeconds; quit" + +Push-Location $BoardDir + +# Execute Renode directly with clean argument quoting +& $RenodeExe --plain --disable-xwt -e "$initCmd" + +Pop-Location + +# Verify success marker in target log +$pass = $false +if (Test-Path $TargetLog) { + $content = Get-Content $TargetLog -Raw -ErrorAction SilentlyContinue + if ($content -and $content.Contains($SuccessMarker)) { + $pass = $true + } +} + +Write-Host "" +Write-Host "==========================================" +if ($pass) { + Write-Host "[PASS] CI Automated Verification Succeeded!" -ForegroundColor Green + if (Test-Path $TargetLog) { + Write-Host "" + Write-Host "Captured UART Output:" + Get-Content $TargetLog | Select-Object -Last 20 | ForEach-Object { Write-Host " $_" } + } + Write-Host "==========================================" + exit 0 +} else { + Write-Host "[FAIL] CI Automated Verification Failed or Timed Out!" -ForegroundColor Red + if (Test-Path $TargetLog) { + Write-Host "" + Write-Host "Captured Log Output:" + Get-Content $TargetLog | ForEach-Object { Write-Host " $_" } + } + Write-Host "==========================================" + exit 1 +} diff --git a/NXP/MIMXRT1064-EVK/scripts/test_headless.sh b/NXP/MIMXRT1064-EVK/scripts/test_headless.sh new file mode 100644 index 00000000..67940c60 --- /dev/null +++ b/NXP/MIMXRT1064-EVK/scripts/test_headless.sh @@ -0,0 +1,150 @@ +#!/usr/bin/env bash +# Copyright (c) 2026 Eclipse ThreadX contributors +# +# 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 NXP i.MX RT1064 port. + +set -e + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +BOARD_DIR="$(cd "${SCRIPT_DIR}/.." && pwd)" +BUILD_DIR="${BOARD_DIR}/build" + +TIMEOUT_SECONDS=24 +SEED="12345" +DEMO="" + +while [[ $# -gt 0 ]]; do + case $1 in + -d|--demo) + DEMO="$2" + shift 2 + ;; + -t|--timeout) + TIMEOUT_SECONDS="$2" + shift 2 + ;; + -s|--seed) + SEED="$2" + shift 2 + ;; + *) + shift + ;; + esac +done + +if [ -n "${DEMO}" ]; then + echo "[INFO] Ensuring demo '${DEMO}' is active and built..." + "${SCRIPT_DIR}/build.sh" --demo "${DEMO}" +fi + +CACHED_DEMO="netx_trng_console" +if [ -n "${DEMO}" ]; then + CACHED_DEMO="${DEMO}" +elif [ -f "${BUILD_DIR}/CMakeCache.txt" ]; then + VAL=$(grep -E "^ACTIVE_DEMO:STRING=" "${BUILD_DIR}/CMakeCache.txt" | cut -d'=' -f2 | tr -d ' \r\n') + if [ -n "${VAL}" ] && [ "${VAL}" != "all" ]; then + CACHED_DEMO="${VAL}" + fi +fi + +DEMO_DIR="${BUILD_DIR}/app/demos/${CACHED_DEMO}" +SERVER_ELF="${DEMO_DIR}/mimxrt1064_threadx.elf" +CLIENT_ELF="${DEMO_DIR}/mimxrt1064_client.elf" + +if [ ! -f "${SERVER_ELF}" ] && [ -f "${BUILD_DIR}/mimxrt1064_threadx.elf" ]; then + SERVER_ELF="${BUILD_DIR}/mimxrt1064_threadx.elf" + CLIENT_ELF="${BUILD_DIR}/mimxrt1064_client.elf" +fi + +if [ ! -f "${SERVER_ELF}" ]; then + echo "[FAIL] Binary ${SERVER_ELF} not found. Please build first using ./scripts/build.sh -d ${CACHED_DEMO}" + exit 1 +fi + +if [ "${CACHED_DEMO}" = "threadx_basic" ]; then + RESC_REL_PATH="renode/mimxrt1064-headless-single.resc" + TARGET_LOG="${BUILD_DIR}/server_uart.log" + SUCCESS_MARKER="Executing periodic task" + TEST_DESC="ThreadX Core Basic Demo (Task Scheduling & GPIO LED)" +else + RESC_REL_PATH="renode/mimxrt1064-headless-multinode.resc" + TARGET_LOG="${BUILD_DIR}/client_uart.log" + SUCCESS_MARKER="VERIFICATION SUCCESS" + TEST_DESC="NetX Duo Multi-Node Networking Demo (${CACHED_DEMO})" +fi + +RENODE_CMD="renode" +if ! command -v renode &> /dev/null; then + if [ -f "/opt/renode/renode" ]; then + RENODE_CMD="/opt/renode/renode" + else + echo "[FAIL] Renode was not found in PATH." + exit 1 + fi +fi + +rm -f "${BUILD_DIR}/server_uart.log" "${BUILD_DIR}/client_uart.log" + +echo "==========================================" +echo "Renode Headless CI Automated Test Runner" +echo "==========================================" +echo "Active Demo: ${CACHED_DEMO}" +echo "Test Suite: ${TEST_DESC}" +echo "Script: ${RESC_REL_PATH}" +if [ -n "${SEED}" ]; then + echo "Seed: ${SEED} (Deterministic)" +fi +echo "Timeout: ${TIMEOUT_SECONDS}s" +echo "Log Target: ${TARGET_LOG}" +echo "" +echo "[INFO] Launching Renode in headless mode..." + +cd "${BOARD_DIR}" + +RENODE_EXEC_CMD="" +if [ -n "${SEED}" ]; then + RENODE_EXEC_CMD="emulation SetSeed ${SEED}; " +fi +RENODE_EXEC_CMD="${RENODE_EXEC_CMD}\$bin = @\"${SERVER_ELF}\"; \$bin_server = @\"${SERVER_ELF}\"; " +if [ -f "${CLIENT_ELF}" ]; then + RENODE_EXEC_CMD="${RENODE_EXEC_CMD}\$bin_client = @\"${CLIENT_ELF}\"; " +fi +RENODE_EXEC_CMD="${RENODE_EXEC_CMD}include @\"${RESC_REL_PATH}\"; sleep ${TIMEOUT_SECONDS}; quit" + +"${RENODE_CMD}" --plain --disable-xwt -e "${RENODE_EXEC_CMD}" || true + +PASS=0 +if [ -f "${TARGET_LOG}" ]; then + if grep -q "${SUCCESS_MARKER}" "${TARGET_LOG}" 2>/dev/null; then + PASS=1 + fi +fi + +echo "" +echo "==========================================" +if [ ${PASS} -eq 1 ]; then + echo "[PASS] CI Automated Verification Succeeded!" + echo "" + echo "Captured UART Output:" + tail -n 20 "${TARGET_LOG}" 2>/dev/null || true + echo "==========================================" + exit 0 +else + echo "[FAIL] CI Automated Verification Failed or Timed Out!" + if [ -f "${TARGET_LOG}" ]; then + echo "" + echo "Captured Log Output:" + cat "${TARGET_LOG}" + fi + echo "==========================================" + exit 1 +fi + From c522d5b0361805df29e33ebd4106de4141605e86 Mon Sep 17 00:00:00 2001 From: Ali Eissa Date: Tue, 15 Sep 2026 07:26:25 +0400 Subject: [PATCH 09/11] ci(mimxrt1064-evk): add GitHub Actions build and Renode headless verification pipeline Signed-off-by: Ali Eissa Assisted-by: Google DeepMind Antigravity --- .github/workflows/ci.yml | 170 ++++++++++++- NXP/MIMXRT1064-EVK/renode/mimxrt1064-evk.repl | 22 +- .../renode/mimxrt1064-headless-multinode.resc | 42 +-- .../renode/mimxrt1064-headless-single.resc | 25 +- NXP/MIMXRT1064-EVK/scripts/pydev/flipflop.py | 7 + NXP/MIMXRT1064-EVK/scripts/pydev/ticker.py | 16 ++ NXP/MIMXRT1064-EVK/scripts/test_headless.ps1 | 146 +---------- NXP/MIMXRT1064-EVK/scripts/test_headless.sh | 139 +--------- NXP/MIMXRT1064-EVK/scripts/test_renode.py | 240 ++++++++++++++++++ 9 files changed, 499 insertions(+), 308 deletions(-) create mode 100644 NXP/MIMXRT1064-EVK/scripts/pydev/flipflop.py create mode 100644 NXP/MIMXRT1064-EVK/scripts/pydev/ticker.py create mode 100644 NXP/MIMXRT1064-EVK/scripts/test_renode.py diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f883765e..99aa5ccf 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -12,9 +12,10 @@ name: SampleX CI Verification Pipeline on: push: - branches: [ main, master, dev, 'feat/**' ] + branches: [ main, master, dev, 'feat/**', 'test/**' ] pull_request: branches: [ main, master, dev ] + workflow_dispatch: jobs: build-riscv-polarfire: @@ -262,3 +263,170 @@ 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 + + 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: Fetch NXP SDK & CMSIS Dependencies + run: | + bash NXP/MIMXRT1064-EVK/scripts/fetch_sdk.sh + + - name: Build All NXP MIMXRT1064-EVK Demos + run: | + bash NXP/MIMXRT1064-EVK/scripts/build.sh --demo all --rebuild + + - name: Verify Built NXP ELFs + run: | + test -f NXP/MIMXRT1064-EVK/build/app/demos/threadx_basic/mimxrt1064_threadx.elf + test -f NXP/MIMXRT1064-EVK/build/app/demos/netx_echo/mimxrt1064_threadx.elf + test -f NXP/MIMXRT1064-EVK/build/app/demos/netx_echo/mimxrt1064_client.elf + test -f NXP/MIMXRT1064-EVK/build/app/demos/netx_trng_console/mimxrt1064_threadx.elf + test -f 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: 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: NXP/MIMXRT1064-EVK/build/app/demos + + - name: Inspect Downloaded ELF Artifacts + run: | + echo "=== Extracted NXP Demo ELF Artifacts ===" + ls -laR 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 NXP/MIMXRT1064-EVK/scripts/test_renode.py --demo threadx_basic + + - name: Run Deterministic Headless Renode Test (netx_echo) + run: | + python3 NXP/MIMXRT1064-EVK/scripts/test_renode.py --demo netx_echo + + - name: Run Deterministic Headless Renode Test (netx_trng_console) + run: | + python3 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: | + NXP/MIMXRT1064-EVK/build/*.log + NXP/MIMXRT1064-EVK/*.log + if-no-files-found: ignore + diff --git a/NXP/MIMXRT1064-EVK/renode/mimxrt1064-evk.repl b/NXP/MIMXRT1064-EVK/renode/mimxrt1064-evk.repl index ee18a571..303e5475 100644 --- a/NXP/MIMXRT1064-EVK/renode/mimxrt1064-evk.repl +++ b/NXP/MIMXRT1064-EVK/renode/mimxrt1064-evk.repl @@ -8,20 +8,7 @@ // // Platform description for NXP i.MX RT1064-EVK (Simulated in Renode). -using "platforms/cpus/imxrt1064.repl" - -// External SDRAM (32 MB @ 0x80000000) -sdram0: Memory.MappedMemory @ sysbus 0x80000000 - size: 0x2000000 - -// External/On-chip FlexSPI NOR Flash (4 MB @ 0x70000000) -flash_mem: Memory.MappedMemory @ sysbus 0x70000000 - size: 0x400000 - -// User Button SW8 (WAKEUP, active low, connected to GPIO5 Pin 0) -user_button: Miscellaneous.Button @ gpio5 - invert: true - -> gpio5@0 +using "platforms/boards/mimxrt1064_evk.repl" // User LED D18 (Green, active low, connected to GPIO1 Pin 9) gpio1: @@ -30,13 +17,6 @@ gpio1: user_led: Miscellaneous.LED @ gpio1 9 invert: true -// On-chip ADCs -adc1: - referenceVoltage: 3.3 - -adc2: - referenceVoltage: 3.3 - // Ethernet Physical Layer (KSZ8081 PHY at address 2 on enet) phy: Network.EthernetPhysicalLayer @ enet 2 Id1: 0x0022 diff --git a/NXP/MIMXRT1064-EVK/renode/mimxrt1064-headless-multinode.resc b/NXP/MIMXRT1064-EVK/renode/mimxrt1064-headless-multinode.resc index 4f695be6..13b1ae9e 100644 --- a/NXP/MIMXRT1064-EVK/renode/mimxrt1064-headless-multinode.resc +++ b/NXP/MIMXRT1064-EVK/renode/mimxrt1064-headless-multinode.resc @@ -10,34 +10,44 @@ # Ali Eissa - 2026 version. :name: MIMXRT1064-EVK Headless Multi-Node CI Test -:description: Headless two-node verification connecting server and client via virtual switch. + +$platform?=$ORIGIN/mimxrt1064-evk.repl +$bin_server?=$ORIGIN/../build/app/demos/netx_echo/mimxrt1064_threadx.elf +$bin_client?=$ORIGIN/../build/app/demos/netx_echo/mimxrt1064_client.elf # 1. Create Virtual Ethernet Switch emulation CreateSwitch "switch" # 2. Server Machine (192.168.0.100) mach create "server" -machine LoadPlatformDescription $ORIGIN/mimxrt1064-evk.repl +machine LoadPlatformDescription $platform connector Connect sysbus.enet switch -sysbus.lpuart1 CreateFileBackend $ORIGIN/../build/server_uart.log true -$bin_server?=$ORIGIN/../build/mimxrt1064_threadx.elf -cpu VectorTableOffset 0x70002000 -sysbus LoadELF $bin_server -cpu PC `sysbus ReadDoubleWord 0x70002004` -cpu SP `sysbus ReadDoubleWord 0x70002000` +macro reset +""" + sysbus LoadELF $bin_server + cpu VectorTableOffset 0x70002000 + cpu PC `sysbus ReadDoubleWord 0x70002004` + cpu SP `sysbus ReadDoubleWord 0x70002000` +""" +runMacro $reset # 3. Client Machine (192.168.0.101) mach create "client" -machine LoadPlatformDescription $ORIGIN/mimxrt1064-evk.repl +machine LoadPlatformDescription $platform connector Connect sysbus.enet switch -sysbus.lpuart1 CreateFileBackend $ORIGIN/../build/client_uart.log true +showAnalyzer sysbus.lpuart1 -$bin_client?=$ORIGIN/../build/mimxrt1064_client.elf -cpu VectorTableOffset 0x70002000 -sysbus LoadELF $bin_client -cpu PC `sysbus ReadDoubleWord 0x70002004` -cpu SP `sysbus ReadDoubleWord 0x70002000` +macro reset +""" + sysbus LoadELF $bin_client + cpu VectorTableOffset 0x70002000 + cpu PC `sysbus ReadDoubleWord 0x70002004` + cpu SP `sysbus ReadDoubleWord 0x70002000` +""" +runMacro $reset # 4. Start Simulation -start +emulation RunFor "6" + +quit diff --git a/NXP/MIMXRT1064-EVK/renode/mimxrt1064-headless-single.resc b/NXP/MIMXRT1064-EVK/renode/mimxrt1064-headless-single.resc index 7e4f74bd..47caa5ce 100644 --- a/NXP/MIMXRT1064-EVK/renode/mimxrt1064-headless-single.resc +++ b/NXP/MIMXRT1064-EVK/renode/mimxrt1064-headless-single.resc @@ -12,15 +12,24 @@ :name: MIMXRT1064-EVK Headless Single-Node CI Test :description: Headless single-node verification capturing LPUART1 output to log file. +using sysbus mach create "mimxrt1064-evk" -machine LoadPlatformDescription $ORIGIN/mimxrt1064-evk.repl +$platform?=$ORIGIN/mimxrt1064-evk.repl +machine LoadPlatformDescription $platform -sysbus.lpuart1 CreateFileBackend $ORIGIN/../build/server_uart.log true +showAnalyzer sysbus.lpuart1 -$bin?=$ORIGIN/../build/mimxrt1064_threadx.elf -cpu VectorTableOffset 0x70002000 -sysbus LoadELF $bin -cpu PC `sysbus ReadDoubleWord 0x70002004` -cpu SP `sysbus ReadDoubleWord 0x70002000` +$bin?=$ORIGIN/../build/app/demos/threadx_basic/mimxrt1064_threadx.elf -start +macro reset +""" + sysbus LoadELF $bin + cpu VectorTableOffset 0x70002000 + cpu PC `sysbus ReadDoubleWord 0x70002004` + cpu SP `sysbus ReadDoubleWord 0x70002000` +""" +runMacro $reset + +emulation RunFor "4" + +quit diff --git a/NXP/MIMXRT1064-EVK/scripts/pydev/flipflop.py b/NXP/MIMXRT1064-EVK/scripts/pydev/flipflop.py new file mode 100644 index 00000000..17232c27 --- /dev/null +++ b/NXP/MIMXRT1064-EVK/scripts/pydev/flipflop.py @@ -0,0 +1,7 @@ +if request.IsInit: + lastVal = 0 +else: + lastVal = 1 - lastVal + request.Value = lastVal * 0xFFFFFFFF + +self.NoisyLog("%s on FLIPFLOP at 0x%x, value 0x%x" % (str(request.Type), request.Offset, request.Value)) diff --git a/NXP/MIMXRT1064-EVK/scripts/pydev/ticker.py b/NXP/MIMXRT1064-EVK/scripts/pydev/ticker.py new file mode 100644 index 00000000..43a27c4e --- /dev/null +++ b/NXP/MIMXRT1064-EVK/scripts/pydev/ticker.py @@ -0,0 +1,16 @@ +INIT_VALUE = 1 +STEP = 2 + +if request.IsInit: + lastVal = 0 + step = 1 +elif request.IsUser: + if request.Offset == INIT_VALUE: + lastVal = request.Value + elif request.Offset == STEP: + step = request.Value +else: + lastVal = lastVal + step + request.Value = lastVal + +self.NoisyLog("%s on TICKER at 0x%x, value 0x%x" % (str(request.Type), request.Offset, request.Value)) diff --git a/NXP/MIMXRT1064-EVK/scripts/test_headless.ps1 b/NXP/MIMXRT1064-EVK/scripts/test_headless.ps1 index 56fb3524..e23e0f62 100644 --- a/NXP/MIMXRT1064-EVK/scripts/test_headless.ps1 +++ b/NXP/MIMXRT1064-EVK/scripts/test_headless.ps1 @@ -10,144 +10,26 @@ # Ali Eissa - 2026 NXP i.MX RT1064 port. param( - [string]$Demo, - [int]$TimeoutSeconds = 24, - [Nullable[int]]$Seed = 12345 + [string]$Demo = "threadx_basic", + [int]$TimeoutSeconds = 300, + [Nullable[int]]$Seed ) -$BoardDir = Resolve-Path "$PSScriptRoot/.." -$BuildDir = Join-Path $BoardDir "build" +$scriptPath = Join-Path $PSScriptRoot "test_renode.py" -# Optional build if Demo parameter is supplied (incremental, no clean rebuild) -if ($Demo) { - Write-Host "[INFO] Ensuring demo '$Demo' is active and built..." - & "$PSScriptRoot/build.ps1" -Demo $Demo - if ($LASTEXITCODE -ne 0) { - Write-Error "[FAIL] Build failed for demo '$Demo'" - exit 1 - } -} - -# Determine active demo -if ($Demo) { - $cachedDemo = $Demo -} else { - $cachedDemo = "netx_trng_console" - $cacheFile = Join-Path $BuildDir "CMakeCache.txt" - if (Test-Path $cacheFile) { - $match = Select-String -Path $cacheFile -Pattern "^ACTIVE_DEMO:STRING=(.*)$" - if ($match) { - $val = $match.Matches.Groups[1].Value.Trim() - if ($val -and $val -ne "all") { - $cachedDemo = $val - } - } - } -} - -$serverElfRel = "build/app/demos/$cachedDemo/mimxrt1064_threadx.elf" -$clientElfRel = "build/app/demos/$cachedDemo/mimxrt1064_client.elf" - -if (-not (Test-Path (Join-Path $BoardDir $serverElfRel)) -and (Test-Path (Join-Path $BoardDir "build/mimxrt1064_threadx.elf"))) { - $serverElfRel = "build/mimxrt1064_threadx.elf" - $clientElfRel = "build/mimxrt1064_client.elf" -} - -$ServerElf = Join-Path $BoardDir $serverElfRel -$ClientElf = Join-Path $BoardDir $clientElfRel - -if (-not (Test-Path $ServerElf)) { - Write-Error "[FAIL] Binary $ServerElf not found. Please build first using .\scripts\build.ps1 -Demo $cachedDemo" - exit 1 -} - -# Configure test mode, script, and pass marker -if ($cachedDemo -eq "threadx_basic") { - $RescRelPath = "renode/mimxrt1064-headless-single.resc" - $TargetLog = Join-Path $BuildDir "server_uart.log" - $SuccessMarker = "Executing periodic task" - $TestDescription = "ThreadX Core Basic Demo (Task Scheduling & GPIO LED)" -} else { - $RescRelPath = "renode/mimxrt1064-headless-multinode.resc" - $TargetLog = Join-Path $BuildDir "client_uart.log" - $SuccessMarker = "VERIFICATION SUCCESS" - $TestDescription = "NetX Duo Multi-Node Networking Demo ($cachedDemo)" -} - -# Find Renode executable -$RenodeExe = (Get-Command renode -ErrorAction SilentlyContinue).Source -if (-not $RenodeExe -and (Test-Path "C:\Program Files\Renode\renode.exe")) { - $RenodeExe = "C:\Program Files\Renode\renode.exe" -} -if (-not $RenodeExe) { - Write-Error "[FAIL] Renode was not found in PATH or at 'C:\Program Files\Renode\renode.exe'." - exit 1 -} - -# Remove stale log files -Remove-Item (Join-Path $BuildDir "server_uart.log") -Force -ErrorAction SilentlyContinue -Remove-Item (Join-Path $BuildDir "client_uart.log") -Force -ErrorAction SilentlyContinue - -Write-Host "==========================================" -Write-Host "Renode Headless CI Automated Test Runner" -Write-Host "==========================================" -Write-Host "Active Demo: $cachedDemo" -Write-Host "Test Suite: $TestDescription" -Write-Host "Script: $RescRelPath" +$pythonArgs = @($scriptPath, "--demo", $Demo, "--timeout", $TimeoutSeconds) if ($null -ne $Seed) { - Write-Host "Seed: $Seed (Deterministic)" + $pythonArgs += @("--seed", $Seed) } -Write-Host "Timeout: ${TimeoutSeconds}s" -Write-Host "Log Target: $TargetLog" -Write-Host "" -Write-Host "[INFO] Launching Renode in headless mode..." -# Build argument list for Renode: pass explicit binary paths, include script, sleep for duration, and quit -# Build argument list for Renode: pass clean relative paths, include script, sleep for duration, and quit -$initCmd = "" -if ($null -ne $Seed) { - $initCmd += "emulation SetSeed $Seed; " -} -$initCmd += "`$bin = @`"$serverElfRel`"; `$bin_server = @`"$serverElfRel`"; " -if (Test-Path $ClientElf) { - $initCmd += "`$bin_client = @`"$clientElfRel`"; " +$pythonExe = (Get-Command python3 -ErrorAction SilentlyContinue).Source +if (-not $pythonExe) { + $pythonExe = (Get-Command python -ErrorAction SilentlyContinue).Source } -$initCmd += "include @$RescRelPath; sleep $TimeoutSeconds; quit" - -Push-Location $BoardDir - -# Execute Renode directly with clean argument quoting -& $RenodeExe --plain --disable-xwt -e "$initCmd" - -Pop-Location - -# Verify success marker in target log -$pass = $false -if (Test-Path $TargetLog) { - $content = Get-Content $TargetLog -Raw -ErrorAction SilentlyContinue - if ($content -and $content.Contains($SuccessMarker)) { - $pass = $true - } -} - -Write-Host "" -Write-Host "==========================================" -if ($pass) { - Write-Host "[PASS] CI Automated Verification Succeeded!" -ForegroundColor Green - if (Test-Path $TargetLog) { - Write-Host "" - Write-Host "Captured UART Output:" - Get-Content $TargetLog | Select-Object -Last 20 | ForEach-Object { Write-Host " $_" } - } - Write-Host "==========================================" - exit 0 -} else { - Write-Host "[FAIL] CI Automated Verification Failed or Timed Out!" -ForegroundColor Red - if (Test-Path $TargetLog) { - Write-Host "" - Write-Host "Captured Log Output:" - Get-Content $TargetLog | ForEach-Object { Write-Host " $_" } - } - Write-Host "==========================================" +if (-not $pythonExe) { + Write-Error "[FAIL] Python was not found in PATH." exit 1 } + +& $pythonExe @pythonArgs +exit $LASTEXITCODE diff --git a/NXP/MIMXRT1064-EVK/scripts/test_headless.sh b/NXP/MIMXRT1064-EVK/scripts/test_headless.sh index 67940c60..24bbc030 100644 --- a/NXP/MIMXRT1064-EVK/scripts/test_headless.sh +++ b/NXP/MIMXRT1064-EVK/scripts/test_headless.sh @@ -13,138 +13,17 @@ set -e SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -BOARD_DIR="$(cd "${SCRIPT_DIR}/.." && pwd)" -BUILD_DIR="${BOARD_DIR}/build" -TIMEOUT_SECONDS=24 -SEED="12345" -DEMO="" - -while [[ $# -gt 0 ]]; do - case $1 in - -d|--demo) - DEMO="$2" - shift 2 - ;; - -t|--timeout) - TIMEOUT_SECONDS="$2" - shift 2 - ;; - -s|--seed) - SEED="$2" - shift 2 - ;; - *) - shift - ;; - esac -done - -if [ -n "${DEMO}" ]; then - echo "[INFO] Ensuring demo '${DEMO}' is active and built..." - "${SCRIPT_DIR}/build.sh" --demo "${DEMO}" -fi - -CACHED_DEMO="netx_trng_console" -if [ -n "${DEMO}" ]; then - CACHED_DEMO="${DEMO}" -elif [ -f "${BUILD_DIR}/CMakeCache.txt" ]; then - VAL=$(grep -E "^ACTIVE_DEMO:STRING=" "${BUILD_DIR}/CMakeCache.txt" | cut -d'=' -f2 | tr -d ' \r\n') - if [ -n "${VAL}" ] && [ "${VAL}" != "all" ]; then - CACHED_DEMO="${VAL}" - fi -fi - -DEMO_DIR="${BUILD_DIR}/app/demos/${CACHED_DEMO}" -SERVER_ELF="${DEMO_DIR}/mimxrt1064_threadx.elf" -CLIENT_ELF="${DEMO_DIR}/mimxrt1064_client.elf" - -if [ ! -f "${SERVER_ELF}" ] && [ -f "${BUILD_DIR}/mimxrt1064_threadx.elf" ]; then - SERVER_ELF="${BUILD_DIR}/mimxrt1064_threadx.elf" - CLIENT_ELF="${BUILD_DIR}/mimxrt1064_client.elf" -fi - -if [ ! -f "${SERVER_ELF}" ]; then - echo "[FAIL] Binary ${SERVER_ELF} not found. Please build first using ./scripts/build.sh -d ${CACHED_DEMO}" - exit 1 -fi - -if [ "${CACHED_DEMO}" = "threadx_basic" ]; then - RESC_REL_PATH="renode/mimxrt1064-headless-single.resc" - TARGET_LOG="${BUILD_DIR}/server_uart.log" - SUCCESS_MARKER="Executing periodic task" - TEST_DESC="ThreadX Core Basic Demo (Task Scheduling & GPIO LED)" -else - RESC_REL_PATH="renode/mimxrt1064-headless-multinode.resc" - TARGET_LOG="${BUILD_DIR}/client_uart.log" - SUCCESS_MARKER="VERIFICATION SUCCESS" - TEST_DESC="NetX Duo Multi-Node Networking Demo (${CACHED_DEMO})" -fi - -RENODE_CMD="renode" -if ! command -v renode &> /dev/null; then - if [ -f "/opt/renode/renode" ]; then - RENODE_CMD="/opt/renode/renode" - else - echo "[FAIL] Renode was not found in PATH." - exit 1 - fi -fi - -rm -f "${BUILD_DIR}/server_uart.log" "${BUILD_DIR}/client_uart.log" - -echo "==========================================" -echo "Renode Headless CI Automated Test Runner" -echo "==========================================" -echo "Active Demo: ${CACHED_DEMO}" -echo "Test Suite: ${TEST_DESC}" -echo "Script: ${RESC_REL_PATH}" -if [ -n "${SEED}" ]; then - echo "Seed: ${SEED} (Deterministic)" -fi -echo "Timeout: ${TIMEOUT_SECONDS}s" -echo "Log Target: ${TARGET_LOG}" -echo "" -echo "[INFO] Launching Renode in headless mode..." - -cd "${BOARD_DIR}" - -RENODE_EXEC_CMD="" -if [ -n "${SEED}" ]; then - RENODE_EXEC_CMD="emulation SetSeed ${SEED}; " -fi -RENODE_EXEC_CMD="${RENODE_EXEC_CMD}\$bin = @\"${SERVER_ELF}\"; \$bin_server = @\"${SERVER_ELF}\"; " -if [ -f "${CLIENT_ELF}" ]; then - RENODE_EXEC_CMD="${RENODE_EXEC_CMD}\$bin_client = @\"${CLIENT_ELF}\"; " -fi -RENODE_EXEC_CMD="${RENODE_EXEC_CMD}include @\"${RESC_REL_PATH}\"; sleep ${TIMEOUT_SECONDS}; quit" - -"${RENODE_CMD}" --plain --disable-xwt -e "${RENODE_EXEC_CMD}" || true - -PASS=0 -if [ -f "${TARGET_LOG}" ]; then - if grep -q "${SUCCESS_MARKER}" "${TARGET_LOG}" 2>/dev/null; then - PASS=1 - fi -fi - -echo "" -echo "==========================================" -if [ ${PASS} -eq 1 ]; then - echo "[PASS] CI Automated Verification Succeeded!" - echo "" - echo "Captured UART Output:" - tail -n 20 "${TARGET_LOG}" 2>/dev/null || true - echo "==========================================" - exit 0 +PYTHON_BIN="" +if command -v python3 &>/dev/null && python3 --version &>/dev/null; then + PYTHON_BIN="python3" +elif command -v python &>/dev/null && python --version &>/dev/null; then + PYTHON_BIN="python" +elif command -v py &>/dev/null && py -3 --version &>/dev/null; then + PYTHON_BIN="py -3" else - echo "[FAIL] CI Automated Verification Failed or Timed Out!" - if [ -f "${TARGET_LOG}" ]; then - echo "" - echo "Captured Log Output:" - cat "${TARGET_LOG}" - fi - echo "==========================================" + echo "[FAIL] Python was not found in PATH." exit 1 fi +exec ${PYTHON_BIN} "${SCRIPT_DIR}/test_renode.py" "$@" diff --git a/NXP/MIMXRT1064-EVK/scripts/test_renode.py b/NXP/MIMXRT1064-EVK/scripts/test_renode.py new file mode 100644 index 00000000..b59b8d5f --- /dev/null +++ b/NXP/MIMXRT1064-EVK/scripts/test_renode.py @@ -0,0 +1,240 @@ +#!/usr/bin/env python3 +# +# Copyright (c) 2026 Eclipse ThreadX contributors +# +# This program and the accompanying materials are made available +# under the terms of the MIT license which is available at +# https://opensource.org/licenses/MIT. +# +# SPDX-License-Identifier: MIT +# +# Contributors: +# Ali Eissa - 2026 NXP i.MX RT1064 port. + +""" +Headless Renode Verification Test for NXP i.MX RT1064-EVK Demos. + +Runs deterministic virtual-time emulation in Antmicro Renode and asserts on +the streamed LPUART1 console output via showAnalyzer. +""" + +import argparse +import os +import queue +import shutil +import subprocess +import sys +import threading +import time + +DEMO_CONFIGS = { + "threadx_basic": { + "description": "ThreadX Core Basic Demo (Task Scheduling & GPIO LED)", + "resc": "mimxrt1064-headless-single.resc", + "multinode": False, + "marker": "Executing periodic task", + }, + "netx_echo": { + "description": "NetX Duo Multi-Node Echo Demo (ICMP, UDP, TCP)", + "resc": "mimxrt1064-headless-multinode.resc", + "multinode": True, + "marker": "[VERIFICATION SUCCESS] ALL NETWORK TESTS PASSED!", + }, + "netx_trng_console": { + "description": "NetX Duo Multi-Node Hardware TRNG & Console Demo", + "resc": "mimxrt1064-headless-multinode.resc", + "multinode": True, + "marker": "[VERIFICATION SUCCESS] ALL TRNG & CONSOLE TESTS PASSED!", + }, +} + + +def find_renode(): + renode_bin = shutil.which("renode") + if renode_bin: + return renode_bin + + candidates = [ + r"C:\Program Files\Renode\renode.exe", + os.path.expanduser(r"~\AppData\Local\Programs\Renode\renode.exe"), + os.path.expanduser(r"~/renode/renode"), + "/opt/renode/renode", + "/usr/bin/renode", + ] + for path in candidates: + if os.path.isfile(path): + return path + + return "renode" + + +def reader_thread_fn(pipe, q): + try: + for line in iter(pipe.readline, ""): + q.put(line) + except Exception: + pass + finally: + pipe.close() + + +def run_test(demo_name, seed=None, timeout_seconds=300): + if demo_name not in DEMO_CONFIGS: + print(f"[FAIL] Unknown demo: {demo_name}. Choices: {list(DEMO_CONFIGS.keys())}") + return 1 + + config = DEMO_CONFIGS[demo_name] + renode = find_renode() + + script_dir = os.path.dirname(os.path.abspath(__file__)) + board_dir = os.path.dirname(script_dir) + build_dir = os.path.join(board_dir, "build") + resc_rel = f"renode/{config['resc']}" + + # Check binary existence + demo_dir = os.path.join(build_dir, "app", "demos", demo_name) + server_elf = os.path.join(demo_dir, "mimxrt1064_threadx.elf") + if not os.path.isfile(server_elf): + fallback = os.path.join(build_dir, "mimxrt1064_threadx.elf") + if os.path.isfile(fallback): + server_elf = fallback + else: + print(f"[FAIL] Server ELF binary not found: {server_elf}") + return 1 + + if config["multinode"]: + client_elf = os.path.join(demo_dir, "mimxrt1064_client.elf") + if not os.path.isfile(client_elf): + fallback_c = os.path.join(build_dir, "mimxrt1064_client.elf") + if not os.path.isfile(fallback_c): + print(f"[FAIL] Client ELF binary not found: {client_elf}") + return 1 + + server_elf_rel = os.path.relpath(server_elf, board_dir).replace("\\", "/") + cmd_parts = [] + if seed is not None: + cmd_parts.append(f"emulation SetSeed {seed}") + + cmd_parts.append("$platform = @renode/mimxrt1064-evk.repl") + + if config["multinode"]: + client_elf_rel = os.path.relpath(client_elf, board_dir).replace("\\", "/") + cmd_parts.append(f"$bin_server = @{server_elf_rel}") + cmd_parts.append(f"$bin_client = @{client_elf_rel}") + else: + cmd_parts.append(f"$bin = @{server_elf_rel}") + + cmd_parts.append(f"include @{resc_rel}") + renode_script_cmd = "; ".join(cmd_parts) + + cmd = [ + renode, + "--plain", + "--disable-gui", + "--port", "-1", + "-e", renode_script_cmd + ] + + print("==========================================") + print("Renode Headless CI Automated Test Runner") + print("==========================================") + print(f"Active Demo: {demo_name}") + print(f"Test Suite: {config['description']}") + print(f"Script: {config['resc']}") + if seed is not None: + print(f"Seed: {seed} (Deterministic)") + print(f"Timeout: {timeout_seconds}s") + print(f"Engine: {renode}") + print("") + print("[INFO] Launching Renode in headless mode...") + print("") + + proc = subprocess.Popen( + cmd, + cwd=board_dir, + stdin=subprocess.PIPE, + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT, + text=True, + bufsize=1, + ) + + os.makedirs(build_dir, exist_ok=True) + log_file_path = os.path.join(build_dir, f"renode_test_{demo_name}.log") + + output_q = queue.Queue() + reader_t = threading.Thread(target=reader_thread_fn, args=(proc.stdout, output_q), daemon=True) + reader_t.start() + + found_marker = False + start_time = time.time() + + with open(log_file_path, "w", encoding="utf-8") as log_f: + try: + while time.time() - start_time < timeout_seconds: + try: + line = output_q.get(timeout=0.1) + sys.stdout.write(line) + sys.stdout.flush() + log_f.write(line) + log_f.flush() + + if config["marker"] in line: + found_marker = True + break + except queue.Empty: + if proc.poll() is not None: + # Drain remaining output + while not output_q.empty(): + line = output_q.get_nowait() + sys.stdout.write(line) + sys.stdout.flush() + log_f.write(line) + log_f.flush() + if config["marker"] in line: + found_marker = True + break + finally: + try: + proc.terminate() + proc.wait(timeout=3) + except Exception: + try: + proc.kill() + except Exception: + pass + + print("") + print("==========================================") + if found_marker: + print(f"[PASS] CI Automated Verification Succeeded for '{demo_name}'!") + print("==========================================") + return 0 + else: + print(f"[FAIL] CI Automated Verification Failed or Timed Out for '{demo_name}'!") + print(f" Expected assertion marker: '{config['marker']}'") + print("==========================================") + return 1 + + +def main(): + parser = argparse.ArgumentParser(description="NXP MIMXRT1064-EVK Headless Renode Test Runner") + parser.add_argument("-d", "--demo", default="threadx_basic", + choices=["threadx_basic", "netx_echo", "netx_trng_console"], + help="Demo application to verify") + parser.add_argument("-s", "--seed", type=int, default=None, + help="Deterministic simulation seed") + parser.add_argument("-t", "--timeout", type=int, default=300, + help="Timeout in seconds (default: 300)") + + args = parser.parse_args() + seed = args.seed + if args.demo == "netx_trng_console" and seed is None: + seed = 12345 + + ret = run_test(args.demo, seed=seed, timeout_seconds=args.timeout) + sys.exit(ret) + + +if __name__ == "__main__": + main() From 9cec8c9a3b0334978bc2ab3731568ec118ca1521 Mon Sep 17 00:00:00 2001 From: Ali Eissa Date: Wed, 16 Sep 2026 16:21:02 +0400 Subject: [PATCH 10/11] feat(nxp): add MIMXRT1064-EVK board enablement with ThreadX, NetX Duo, and Renode simulation - Relocate target under targets/NXP/MIMXRT1064-EVK with modular BSP architecture - Provide ThreadX basic, NetX Duo echo, and TRNG console demos - Vendor NetX Duo Ethernet driver and KSZ8081 PHY driver - Align TRNG bring-up, entropy extraction, and status verification - Enforce thread-safe heap (_sbrk) and console mutex protection - Expand thread stacks to 2KB and enable stack checking - Pin official NXP SDK and CMSIS dependencies with SHA-256 verification - Deduplicate CMake targets with mimxrt1064_common INTERFACE library - Integrate headless single-node and multi-node Renode CI verification Signed-off-by: Ali Eissa Assisted-by: Google DeepMind Antigravity --- .github/workflows/ci.yml | 42 +- NXP/MIMXRT1064-EVK/NOTICE.md | 65 - NXP/MIMXRT1064-EVK/README.md | 259 -- NXP/MIMXRT1064-EVK/app/board_init.h | 32 - NXP/MIMXRT1064-EVK/app/console.c | 87 - NXP/MIMXRT1064-EVK/app/console.h | 34 - NXP/MIMXRT1064-EVK/app/sysmem.c | 50 - NXP/MIMXRT1064-EVK/app/trng.c | 91 - NXP/MIMXRT1064-EVK/scripts/fetch_sdk.sh | 158 - NXP/MIMXRT1064-EVK/scripts/pydev/flipflop.py | 7 - NXP/MIMXRT1064-EVK/scripts/pydev/ticker.py | 16 - .../NXP}/MIMXRT1064-EVK/.gitignore | 0 .../NXP}/MIMXRT1064-EVK/CMakeLists.txt | 205 +- targets/NXP/MIMXRT1064-EVK/NOTICE.md | 128 + targets/NXP/MIMXRT1064-EVK/README.md | 266 ++ .../NXP}/MIMXRT1064-EVK/app/MIMXRT1062.h | 6 +- .../NXP}/MIMXRT1064-EVK/app/ansi_colors.h | 0 .../app/demos/netx_echo/CMakeLists.txt | 41 - .../app/demos/netx_echo/client_main.c | 106 +- .../MIMXRT1064-EVK/app/demos/netx_echo/main.c | 68 +- .../app/demos/netx_echo/test_echo.ps1 | 0 .../app/demos/netx_echo/test_echo.sh | 0 .../demos/netx_trng_console/CMakeLists.txt | 41 - .../app/demos/netx_trng_console/client_main.c | 87 +- .../app/demos/netx_trng_console/main.c | 103 +- .../app/demos/threadx_basic/CMakeLists.txt | 21 - .../app/demos/threadx_basic/main.c | 24 +- .../startup/MIMXRT1064xxxxx_flexspi_nor.ld | 0 .../app/startup/startup_mimxrt1064.S | 0 .../app/startup/tx_initialize_low_level.S | 0 .../NXP}/MIMXRT1064-EVK/app/syscalls.c | 0 targets/NXP/MIMXRT1064-EVK/app/sysmem.c | 104 + targets/NXP/MIMXRT1064-EVK/app/trng.c | 197 ++ .../NXP}/MIMXRT1064-EVK/app/trng.h | 0 .../cmake/arm-gcc-cortex-m7.cmake | 0 .../cmake/arm-gcc-cortex-toolchain.cmake | 0 .../NXP}/MIMXRT1064-EVK/cmake/utilities.cmake | 0 .../NXP/MIMXRT1064-EVK/lib/bsp/CMakeLists.txt | 52 + .../lib/bsp/include/board_config.h | 34 + .../MIMXRT1064-EVK/lib/bsp/src/bsp_board.c | 37 +- .../MIMXRT1064-EVK/lib/bsp/src/bsp_console.c | 162 + .../NXP/MIMXRT1064-EVK/lib/bsp/src/bsp_led.c | 52 + .../MIMXRT1064-EVK/lib/bsp/src/bsp_memory.c | 23 + .../MIMXRT1064-EVK/lib/bsp/src/bsp_selftest.c | 51 + .../gnu/nx_driver_imxrt1062_low_level.S | 84 + .../lib/netx_driver/nx_driver_imxrt1062.c | 2870 +++++++++++++++++ .../lib/netx_driver/nx_driver_imxrt1062.h | 244 ++ .../NXP}/MIMXRT1064-EVK/lib/netxduo/nx_user.h | 0 .../MIMXRT1064-EVK/lib/phyksz8081/fsl_phy.c | 301 ++ .../MIMXRT1064-EVK/lib/phyksz8081/fsl_phy.h | 200 ++ .../NXP}/MIMXRT1064-EVK/lib/threadx/tx_user.h | 3 + .../MIMXRT1064-EVK/renode/mimxrt1064-evk.repl | 0 .../MIMXRT1064-EVK/renode/mimxrt1064-evk.resc | 2 +- .../renode/mimxrt1064-headless-multinode.resc | 0 .../renode/mimxrt1064-headless-single.resc | 0 .../renode/mimxrt1064-network-multinode.resc | 0 .../renode/mimxrt1064-trng-console.resc | 0 .../NXP}/MIMXRT1064-EVK/scripts/build.ps1 | 0 .../NXP}/MIMXRT1064-EVK/scripts/build.sh | 0 .../NXP}/MIMXRT1064-EVK/scripts/fetch_sdk.ps1 | 151 +- .../NXP/MIMXRT1064-EVK/scripts/fetch_sdk.sh | 160 + .../NXP}/MIMXRT1064-EVK/scripts/simulate.ps1 | 0 .../NXP}/MIMXRT1064-EVK/scripts/simulate.sh | 0 .../MIMXRT1064-EVK/scripts/test_headless.ps1 | 0 .../MIMXRT1064-EVK/scripts/test_headless.sh | 0 .../MIMXRT1064-EVK/scripts/test_renode.py | 4 +- 66 files changed, 5403 insertions(+), 1265 deletions(-) delete mode 100644 NXP/MIMXRT1064-EVK/NOTICE.md delete mode 100644 NXP/MIMXRT1064-EVK/README.md delete mode 100644 NXP/MIMXRT1064-EVK/app/board_init.h delete mode 100644 NXP/MIMXRT1064-EVK/app/console.c delete mode 100644 NXP/MIMXRT1064-EVK/app/console.h delete mode 100644 NXP/MIMXRT1064-EVK/app/sysmem.c delete mode 100644 NXP/MIMXRT1064-EVK/app/trng.c delete mode 100644 NXP/MIMXRT1064-EVK/scripts/fetch_sdk.sh delete mode 100644 NXP/MIMXRT1064-EVK/scripts/pydev/flipflop.py delete mode 100644 NXP/MIMXRT1064-EVK/scripts/pydev/ticker.py rename {NXP => targets/NXP}/MIMXRT1064-EVK/.gitignore (100%) rename {NXP => targets/NXP}/MIMXRT1064-EVK/CMakeLists.txt (52%) create mode 100644 targets/NXP/MIMXRT1064-EVK/NOTICE.md create mode 100644 targets/NXP/MIMXRT1064-EVK/README.md rename {NXP => targets/NXP}/MIMXRT1064-EVK/app/MIMXRT1062.h (91%) rename {NXP => targets/NXP}/MIMXRT1064-EVK/app/ansi_colors.h (100%) rename {NXP => targets/NXP}/MIMXRT1064-EVK/app/demos/netx_echo/CMakeLists.txt (59%) rename {NXP => targets/NXP}/MIMXRT1064-EVK/app/demos/netx_echo/client_main.c (76%) rename {NXP => targets/NXP}/MIMXRT1064-EVK/app/demos/netx_echo/main.c (82%) rename {NXP => targets/NXP}/MIMXRT1064-EVK/app/demos/netx_echo/test_echo.ps1 (100%) rename {NXP => targets/NXP}/MIMXRT1064-EVK/app/demos/netx_echo/test_echo.sh (100%) rename {NXP => targets/NXP}/MIMXRT1064-EVK/app/demos/netx_trng_console/CMakeLists.txt (59%) rename {NXP => targets/NXP}/MIMXRT1064-EVK/app/demos/netx_trng_console/client_main.c (75%) rename {NXP => targets/NXP}/MIMXRT1064-EVK/app/demos/netx_trng_console/main.c (80%) rename {NXP => targets/NXP}/MIMXRT1064-EVK/app/demos/threadx_basic/CMakeLists.txt (61%) rename {NXP => targets/NXP}/MIMXRT1064-EVK/app/demos/threadx_basic/main.c (90%) rename {NXP => targets/NXP}/MIMXRT1064-EVK/app/startup/MIMXRT1064xxxxx_flexspi_nor.ld (100%) rename {NXP => targets/NXP}/MIMXRT1064-EVK/app/startup/startup_mimxrt1064.S (100%) rename {NXP => targets/NXP}/MIMXRT1064-EVK/app/startup/tx_initialize_low_level.S (100%) rename {NXP => targets/NXP}/MIMXRT1064-EVK/app/syscalls.c (100%) create mode 100644 targets/NXP/MIMXRT1064-EVK/app/sysmem.c create mode 100644 targets/NXP/MIMXRT1064-EVK/app/trng.c rename {NXP => targets/NXP}/MIMXRT1064-EVK/app/trng.h (100%) rename {NXP => targets/NXP}/MIMXRT1064-EVK/cmake/arm-gcc-cortex-m7.cmake (100%) rename {NXP => targets/NXP}/MIMXRT1064-EVK/cmake/arm-gcc-cortex-toolchain.cmake (100%) rename {NXP => targets/NXP}/MIMXRT1064-EVK/cmake/utilities.cmake (100%) create mode 100644 targets/NXP/MIMXRT1064-EVK/lib/bsp/CMakeLists.txt create mode 100644 targets/NXP/MIMXRT1064-EVK/lib/bsp/include/board_config.h rename NXP/MIMXRT1064-EVK/app/board_init.c => targets/NXP/MIMXRT1064-EVK/lib/bsp/src/bsp_board.c (57%) create mode 100644 targets/NXP/MIMXRT1064-EVK/lib/bsp/src/bsp_console.c create mode 100644 targets/NXP/MIMXRT1064-EVK/lib/bsp/src/bsp_led.c create mode 100644 targets/NXP/MIMXRT1064-EVK/lib/bsp/src/bsp_memory.c create mode 100644 targets/NXP/MIMXRT1064-EVK/lib/bsp/src/bsp_selftest.c create mode 100644 targets/NXP/MIMXRT1064-EVK/lib/netx_driver/gnu/nx_driver_imxrt1062_low_level.S create mode 100644 targets/NXP/MIMXRT1064-EVK/lib/netx_driver/nx_driver_imxrt1062.c create mode 100644 targets/NXP/MIMXRT1064-EVK/lib/netx_driver/nx_driver_imxrt1062.h rename {NXP => targets/NXP}/MIMXRT1064-EVK/lib/netxduo/nx_user.h (100%) create mode 100644 targets/NXP/MIMXRT1064-EVK/lib/phyksz8081/fsl_phy.c create mode 100644 targets/NXP/MIMXRT1064-EVK/lib/phyksz8081/fsl_phy.h rename {NXP => targets/NXP}/MIMXRT1064-EVK/lib/threadx/tx_user.h (94%) rename {NXP => targets/NXP}/MIMXRT1064-EVK/renode/mimxrt1064-evk.repl (100%) rename {NXP => targets/NXP}/MIMXRT1064-EVK/renode/mimxrt1064-evk.resc (95%) rename {NXP => targets/NXP}/MIMXRT1064-EVK/renode/mimxrt1064-headless-multinode.resc (100%) rename {NXP => targets/NXP}/MIMXRT1064-EVK/renode/mimxrt1064-headless-single.resc (100%) rename {NXP => targets/NXP}/MIMXRT1064-EVK/renode/mimxrt1064-network-multinode.resc (100%) rename {NXP => targets/NXP}/MIMXRT1064-EVK/renode/mimxrt1064-trng-console.resc (100%) rename {NXP => targets/NXP}/MIMXRT1064-EVK/scripts/build.ps1 (100%) rename {NXP => targets/NXP}/MIMXRT1064-EVK/scripts/build.sh (100%) rename {NXP => targets/NXP}/MIMXRT1064-EVK/scripts/fetch_sdk.ps1 (54%) create mode 100644 targets/NXP/MIMXRT1064-EVK/scripts/fetch_sdk.sh rename {NXP => targets/NXP}/MIMXRT1064-EVK/scripts/simulate.ps1 (100%) rename {NXP => targets/NXP}/MIMXRT1064-EVK/scripts/simulate.sh (100%) rename {NXP => targets/NXP}/MIMXRT1064-EVK/scripts/test_headless.ps1 (100%) rename {NXP => targets/NXP}/MIMXRT1064-EVK/scripts/test_headless.sh (100%) rename {NXP => targets/NXP}/MIMXRT1064-EVK/scripts/test_renode.py (98%) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 99aa5ccf..0a02c051 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -12,7 +12,7 @@ name: SampleX CI Verification Pipeline on: push: - branches: [ main, master, dev, 'feat/**', 'test/**' ] + branches: [ main, master, dev, 'feat/**' ] pull_request: branches: [ main, master, dev ] workflow_dispatch: @@ -271,6 +271,8 @@ jobs: 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 @@ -311,28 +313,36 @@ jobs: - 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 NXP/MIMXRT1064-EVK/scripts/fetch_sdk.sh + bash targets/NXP/MIMXRT1064-EVK/scripts/fetch_sdk.sh - name: Build All NXP MIMXRT1064-EVK Demos run: | - bash NXP/MIMXRT1064-EVK/scripts/build.sh --demo all --rebuild + bash targets/NXP/MIMXRT1064-EVK/scripts/build.sh --demo all --rebuild - name: Verify Built NXP ELFs run: | - test -f NXP/MIMXRT1064-EVK/build/app/demos/threadx_basic/mimxrt1064_threadx.elf - test -f NXP/MIMXRT1064-EVK/build/app/demos/netx_echo/mimxrt1064_threadx.elf - test -f NXP/MIMXRT1064-EVK/build/app/demos/netx_echo/mimxrt1064_client.elf - test -f NXP/MIMXRT1064-EVK/build/app/demos/netx_trng_console/mimxrt1064_threadx.elf - test -f NXP/MIMXRT1064-EVK/build/app/demos/netx_trng_console/mimxrt1064_client.elf + 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: NXP/MIMXRT1064-EVK/build/app/demos/ + path: targets/NXP/MIMXRT1064-EVK/build/app/demos/ retention-days: 1 test-nxp-renode: @@ -359,12 +369,12 @@ jobs: uses: actions/download-artifact@v4 with: name: nxp-mimxrt1064-demo-elfs - path: NXP/MIMXRT1064-EVK/build/app/demos + path: targets/NXP/MIMXRT1064-EVK/build/app/demos - name: Inspect Downloaded ELF Artifacts run: | echo "=== Extracted NXP Demo ELF Artifacts ===" - ls -laR NXP/MIMXRT1064-EVK/build/app/demos/ + ls -laR targets/NXP/MIMXRT1064-EVK/build/app/demos/ - name: Cache the portable Renode environment id: cache-renode @@ -410,15 +420,15 @@ jobs: - name: Run Deterministic Headless Renode Test (threadx_basic) run: | - python3 NXP/MIMXRT1064-EVK/scripts/test_renode.py --demo threadx_basic + python3 targets/NXP/MIMXRT1064-EVK/scripts/test_renode.py --demo threadx_basic - name: Run Deterministic Headless Renode Test (netx_echo) run: | - python3 NXP/MIMXRT1064-EVK/scripts/test_renode.py --demo netx_echo + python3 targets/NXP/MIMXRT1064-EVK/scripts/test_renode.py --demo netx_echo - name: Run Deterministic Headless Renode Test (netx_trng_console) run: | - python3 NXP/MIMXRT1064-EVK/scripts/test_renode.py --demo netx_trng_console --seed 12345 + python3 targets/NXP/MIMXRT1064-EVK/scripts/test_renode.py --demo netx_trng_console --seed 12345 - name: Upload Renode Execution Logs if: always() @@ -426,7 +436,7 @@ jobs: with: name: nxp-renode-execution-logs path: | - NXP/MIMXRT1064-EVK/build/*.log - NXP/MIMXRT1064-EVK/*.log + targets/NXP/MIMXRT1064-EVK/build/*.log + targets/NXP/MIMXRT1064-EVK/*.log if-no-files-found: ignore diff --git a/NXP/MIMXRT1064-EVK/NOTICE.md b/NXP/MIMXRT1064-EVK/NOTICE.md deleted file mode 100644 index d60251c0..00000000 --- a/NXP/MIMXRT1064-EVK/NOTICE.md +++ /dev/null @@ -1,65 +0,0 @@ -# Third-Party Software Notices - -This directory contains third-party software components included in the repository as well as build automation scripts and configurations that download and compile external dependencies. This notice lists the licenses and copyrights applicable to those components. - ---- - -## 1. NXP MCUXpresso SDK Drivers, Device Support & Startup Files -* **Source**: https://github.com/nxp-mcuxpresso/mcuxsdk-core / https://github.com/nxp-mcuxpresso/mcuxsdk-examples / https://mcuxpresso.nxp.com -* **Location**: `app/startup/startup_mimxrt1064.S`, `app/startup/MIMXRT1064xxxxx_flexspi_nor.ld`, and `lib/mcux-sdk/` -* **License**: BSD 3-Clause - -```text -Copyright (c) 2015-2016, Freescale Semiconductor, Inc. -Copyright 2018-2025 NXP - -The BSD 3 Clause License - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -1. Redistributions of source code must retain the above copyright notice, this -list of conditions and the following disclaimer. - -2. Redistributions in binary form must reproduce the above copyright notice, -this list of conditions and the following disclaimer in the documentation -and/or other materials provided with the distribution. - -3. Neither the name of the copyright holder nor the names of its contributors -may be used to endorse or promote products derived from this software without -specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -``` - ---- - -## 2. ARM CMSIS Core -* **Source**: https://github.com/ARM-software/CMSIS_5 -* **Location**: `lib/mcux-sdk/CMSIS/Include/` -* **License**: Apache License 2.0 - -```text -Copyright (c) 2009-2025 Arm Limited. All rights reserved. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -``` diff --git a/NXP/MIMXRT1064-EVK/README.md b/NXP/MIMXRT1064-EVK/README.md deleted file mode 100644 index 944aded2..00000000 --- a/NXP/MIMXRT1064-EVK/README.md +++ /dev/null @@ -1,259 +0,0 @@ -# NXP i.MX RT1064-EVK Board Enablement Demos - -This directory contains the Board Support Package (BSP) and build configurations for running the **Eclipse ThreadX RTOS** and **NetX Duo TCP/IP stack** on the **NXP i.MX RT1064-EVK** evaluation board (ARM Cortex-M7 @ 600 MHz). - -The project features a decoupled Board Support Package (`board_bsp`) that hides all low-level hardware initializations (clocks, power, caches, MPU regions, pin muxing, Ethernet MAC/PHY descriptors, and on-chip cryptographic peripherals) from the high-level application code. - -> [!NOTE] -> **Hardware Verification Status**: *Simulated in Renode, Pending Physical Hardware Verification* -> -> All peripheral drivers, hardware cryptographic subsystems, and network stacks documented in this repository have been fully verified under multi-node system emulation in Antmicro Renode. Flashing instructions for physical silicon follow standard NXP OpenSDA, Segger J-Link, pyOCD, and MCUXpresso workflows as detailed in the [Physical Board Deployment & Flashing](#physical-board-deployment--flashing) section below. - ---- - -## Supported Demos - -Each demo outputs into its own isolated directory in `build/app/demos//`: - -| Demo Name | Description | Output Directory | -| :--- | :--- | :--- | -| **`threadx_basic`** | Core ThreadX RTOS demo: preemptive thread scheduling, timer callbacks, and User LED D18 heartbeat blinking. | `build/app/demos/threadx_basic/` | -| **`netx_echo`** | NetX Duo networking demo: KSZ8081 Ethernet PHY, ARP, ICMP Ping responder, UDP echo (port 7), and TCP echo server (port 7). | `build/app/demos/netx_echo/` | -| **`netx_trng_console`** *(Default)* | Hardware cryptographic True Random Number Generator (TRNG @ `0x400CC000`) with an interactive TCP diagnostic management shell on port 23. | `build/app/demos/netx_trng_console/` | - ---- - -## Hardware Overview - -* **Evaluation Board**: NXP MIMXRT1064-EVK (ARM Cortex-M7 @ 600 MHz) -* **Memory**: 4 MB on-chip FlexSPI NOR Flash (`0x70000000`), 1 MB on-chip SRAM (ITCM, DTCM, NonCacheable OCRAM) -* **Serial Console**: LPUART1 via OpenSDA micro-USB (`J41`), 115,200 baud, 8N1 -* **User LED & Button**: Green LED `D18` (`GPIO1_IO09`), SW8 WAKEUP button (`GPIO5_IO00`) -* **Ethernet**: ENET MAC + Microchip KSZ8081RNA PHY via RMII -* **TRNG Hardware**: On-chip True Random Number Generator (`0x400CC000`) - ---- - -## Prerequisites - -* **ARM GNU Toolchain** (`arm-none-eabi-gcc` 10.3+) -* **CMake** (3.20+) and **Ninja** (recommended) or Make -* **Git** (for downloading SDK dependencies) -* **Antmicro Renode** (1.15.3+, for simulation) - ---- - -## Quick Start Guide - -### 1. Download SDK Dependencies -Download the stock NXP MCUXpresso SDK drivers, CMSIS headers, and board files: - -* **Windows**: - ```powershell - powershell -ExecutionPolicy Bypass -File .\scripts\fetch_sdk.ps1 - ``` -* **Linux / macOS**: - ```bash - chmod +x ./scripts/fetch_sdk.sh && ./scripts/fetch_sdk.sh - ``` - -### 2. Build the Demos - -#### Option A: Build All Demos (Default & Recommended) -Build all three demos at once. Once built, you can switch between simulations instantly without rebuilding! - -* **Windows**: - ```powershell - powershell -ExecutionPolicy Bypass -File .\scripts\build.ps1 - ``` -* **Linux / macOS**: - ```bash - chmod +x ./scripts/build.sh && ./scripts/build.sh - ``` -* **Direct CMake**: - ```bash - cmake -B build -G Ninja -DACTIVE_DEMO=all - cmake --build build - ``` - -#### Option B: Build a Specific Demo -To build only one specific demo: - -```powershell -# Windows PowerShell -.\scripts\build.ps1 -Demo threadx_basic -.\scripts\build.ps1 -Demo netx_echo -.\scripts\build.ps1 -Demo netx_trng_console -``` - -```bash -# Linux / macOS Bash -./scripts/build.sh -d threadx_basic -./scripts/build.sh -d netx_echo -./scripts/build.sh -d netx_trng_console -``` - -Each demo's artifacts (`.elf`, `.bin`, `.hex`, `.map`) are placed in `build/app/demos//`. - ---- - -## Renode Simulation - -The project includes preconfigured Renode emulation environments for both single-node and multi-node scenarios. - -### 1. Interactive Simulation -Simulate any demo simply by passing the `-Demo` configuration variable: - -* **Windows (PowerShell)**: - ```powershell - # ThreadX Core Basic (single node) - powershell -ExecutionPolicy Bypass -File .\scripts\simulate.ps1 -Demo threadx_basic - - # NetX Duo Network Echo (multi-node server + client) - powershell -ExecutionPolicy Bypass -File .\scripts\simulate.ps1 -Demo netx_echo - - # Hardware TRNG Diagnostic Console (multi-node server + client) - powershell -ExecutionPolicy Bypass -File .\scripts\simulate.ps1 -Demo netx_trng_console - ``` - -* **Linux / macOS (Bash)**: - ```bash - ./scripts/simulate.sh -d threadx_basic - ./scripts/simulate.sh -d netx_echo - ./scripts/simulate.sh -d netx_trng_console - ``` - -#### Deterministic Seeding Option: -For deterministic execution and repeatable TRNG random sequences in simulation, pass `-Seed `: -```powershell -powershell -ExecutionPolicy Bypass -File .\scripts\simulate.ps1 -Demo netx_trng_console -Seed 12345 -``` -```bash -./scripts/simulate.sh -d netx_trng_console -s 12345 -``` - -### 2. Headless Automated Regression Testing (CI/CD) -The project provides headless test runners (`test_headless.ps1` and `test_headless.sh`) designed for continuous integration pipelines without a graphical display. The runner boots the simulation, monitors the virtual UART logs, and exits with code `0` on success or code `1` on timeout/failure. - -* **Windows (PowerShell)**: - ```powershell - powershell -ExecutionPolicy Bypass -File .\scripts\test_headless.ps1 - ``` -* **Linux / macOS (Bash)**: - ```bash - chmod +x ./scripts/test_headless.sh - ./scripts/test_headless.sh - ``` - -Test any specific demo headlessly: -```powershell -powershell -ExecutionPolicy Bypass -File .\scripts\test_headless.ps1 -Demo threadx_basic -TimeoutSeconds 8 -``` - ---- - -## Physical Board Deployment & Flashing - -> [!NOTE] -> *Simulated in Renode, Pending Physical Hardware Verification* - -When flashing to physical hardware, ensure the EVK board boot mode switches (`SW7`: `1-OFF, 2-ON, 3-OFF, 4-ON`) are configured for **Internal Boot (FlexSPI NOR Flash)**. Connect your PC to the OpenSDA USB port (`J41`). - -### Flashing Method 1: OpenSDA Drag-and-Drop (DAP-Link) -1. Connect the EVK board to your PC via micro-USB connector `J41`. -2. The onboard OpenSDA circuit mounts as a USB mass storage drive (e.g., `RT1064-EVK`). -3. Copy `build/app/demos//mimxrt1064_threadx.bin` and paste it directly into the `RT1064-EVK` drive. -4. The OpenSDA LED blinks rapidly during programming. Once complete, press the `SW3` (RESET) button to boot. - -### Flashing Method 2: SEGGER J-Link -If using a SEGGER J-Link probe (or OpenSDA programmed with J-Link firmware): -1. Connect via J-Link Commander: - ```text - JLink.exe -device MIMXRT1064xxx6A -if SWD -speed 4000 -autoconnect 1 - ``` -2. Flash the raw binary or hex file: - ```text - loadfile build/app/demos//mimxrt1064_threadx.hex - r - g - ``` - -### Flashing Method 3: pyOCD Command Line -Using the open-source pyOCD programmer: -1. Install pyOCD and the NXP device pack: - ```bash - pip install pyocd && pyocd pack install MIMXRT1064 - ``` -2. Program the target: - ```bash - pyocd flash -t mimxrt1064 build/app/demos//mimxrt1064_threadx.hex - ``` - -### Flashing Method 4: NXP MCUXpresso IDE / GUI Flash Tool -1. Open MCUXpresso IDE and select **GUI Flash Tool** from the toolbar. -2. Select target device `MIMXRT1064xxxxA` and target memory `PROGRAM_FLASH` (`0x70000000`). -3. Select `build/app/demos//mimxrt1064_threadx.elf` (or `.bin`) and click **Program**. - ---- - -## Developer Guide: How to Add a New Demo - -The decoupled architecture of `board_bsp` makes adding custom applications straightforward: - -### Step 1: Create the Demo Directory -Create a folder under `app/demos/` (e.g., `app/demos/my_new_demo/`). - -### Step 2: Write Application Code -Create `main.c` utilizing the clean BSP initialization API: -```c -#include "board_init.h" -#include "console.h" -#include "tx_api.h" - -int main(void) -{ - /* Initialize MPU, 600 MHz system clocks, and GPIO pins */ - board_init(); - - /* Initialize LPUART1 serial console */ - console_init(); - - /* Optional: Initialize Ethernet MAC/PHY if using networking */ - // board_ethernet_init(); - - /* Enter ThreadX RTOS Kernel */ - tx_kernel_enter(); - return 0; -} -``` - -### Step 3: Create `CMakeLists.txt` -In your demo directory: -```cmake -set(DEMO_TARGET "demo_my_new_demo") -add_executable(${DEMO_TARGET} - main.c -) -set_target_properties(${DEMO_TARGET} PROPERTIES OUTPUT_NAME "mimxrt1064_threadx") - -target_include_directories(${DEMO_TARGET} PRIVATE - ${CMAKE_CURRENT_SOURCE_DIR} - ${CMAKE_CURRENT_SOURCE_DIR}/../.. -) - -target_link_libraries(${DEMO_TARGET} PRIVATE - board_bsp - threadx - # netxduo # Uncomment if using network - # netx_imxrt_driver # Uncomment if using network -) - -set_target_linker(${DEMO_TARGET} "${CMAKE_CURRENT_SOURCE_DIR}/../../startup/MIMXRT1064xxxxx_flexspi_nor.ld") -post_build(${DEMO_TARGET}) -``` - -### Step 4: Build and Simulate -```bash -cmake -DACTIVE_DEMO=my_new_demo -B build -G Ninja -cmake --build build -``` diff --git a/NXP/MIMXRT1064-EVK/app/board_init.h b/NXP/MIMXRT1064-EVK/app/board_init.h deleted file mode 100644 index c87f7a40..00000000 --- a/NXP/MIMXRT1064-EVK/app/board_init.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (c) 2026 Eclipse ThreadX contributors - * - * 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. - */ - -#ifndef BOARD_INIT_H -#define BOARD_INIT_H - -#include "fsl_common.h" -#include "board.h" -#include "pin_mux.h" -#include "clock_config.h" - -#ifdef __cplusplus -extern "C" { -#endif - -void board_init(void); - -#ifdef __cplusplus -} -#endif - -#endif /* BOARD_INIT_H */ diff --git a/NXP/MIMXRT1064-EVK/app/console.c b/NXP/MIMXRT1064-EVK/app/console.c deleted file mode 100644 index 5befef29..00000000 --- a/NXP/MIMXRT1064-EVK/app/console.c +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright (c) 2026 Eclipse ThreadX contributors - * - * 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. - */ - -#include "console.h" -#include "fsl_lpuart.h" -#include "board.h" - -void console_init(void) -{ - lpuart_config_t config; - - LPUART_GetDefaultConfig(&config); - config.baudRate_Bps = 115200U; - config.enableTx = true; - config.enableRx = true; - - uint32_t uartClkSrcFreq = BOARD_DebugConsoleSrcFreq(); - LPUART_Init(LPUART1, &config, uartClkSrcFreq); -} - -void console_putc(char c) -{ - if (c == '\n') - { - while (!(LPUART_GetStatusFlags(LPUART1) & (uint32_t)kLPUART_TxDataRegEmptyFlag)) - { - } - LPUART_WriteByte(LPUART1, (uint8_t)'\r'); - } - - while (!(LPUART_GetStatusFlags(LPUART1) & (uint32_t)kLPUART_TxDataRegEmptyFlag)) - { - } - LPUART_WriteByte(LPUART1, (uint8_t)c); -} - -void console_write(const char *str) -{ - while (*str != '\0') - { - console_putc(*str++); - } -} - -int __io_putchar(int ch) -{ - console_putc((char)ch); - return ch; -} - -int __io_getchar(void) -{ - while (!(LPUART_GetStatusFlags(LPUART1) & (uint32_t)kLPUART_RxDataRegFullFlag)) - { - } - return (int)LPUART_ReadByte(LPUART1); -} - -int _write(int file, char *ptr, int len) -{ - (void)file; - for (int i = 0; i < len; i++) - { - console_putc(ptr[i]); - } - return len; -} - -int _read(int file, char *ptr, int len) -{ - (void)file; - for (int i = 0; i < len; i++) - { - ptr[i] = (char)__io_getchar(); - } - return len; -} diff --git a/NXP/MIMXRT1064-EVK/app/console.h b/NXP/MIMXRT1064-EVK/app/console.h deleted file mode 100644 index 3907e183..00000000 --- a/NXP/MIMXRT1064-EVK/app/console.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (c) 2026 Eclipse ThreadX contributors - * - * 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. - */ - -#ifndef CONSOLE_H -#define CONSOLE_H - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -void console_init(void); -void console_putc(char c); -void console_write(const char *str); -int __io_putchar(int ch); -int __io_getchar(void); - -#ifdef __cplusplus -} -#endif - -#endif /* CONSOLE_H */ diff --git a/NXP/MIMXRT1064-EVK/app/sysmem.c b/NXP/MIMXRT1064-EVK/app/sysmem.c deleted file mode 100644 index 4d7954bc..00000000 --- a/NXP/MIMXRT1064-EVK/app/sysmem.c +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2026 Eclipse ThreadX contributors - * - * 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. - */ - -#include -#include -#include - -/** - * Pointer to the current high watermark of the heap usage - */ -static uint8_t *__sbrk_heap_end = NULL; - -/** - * @brief _sbrk() allocates memory to the newlib heap and is used by malloc. - */ -void *_sbrk(ptrdiff_t incr) -{ - extern uint8_t _end; - extern uint8_t __StackLimit; - const uint8_t *max_heap = &__StackLimit; - uint8_t *prev_heap_end; - - /* Initialize heap end at first call */ - if (NULL == __sbrk_heap_end) - { - __sbrk_heap_end = &_end; - } - - /* Protect heap from growing into stack */ - if (__sbrk_heap_end + incr > max_heap) - { - errno = ENOMEM; - return (void *)-1; - } - - prev_heap_end = __sbrk_heap_end; - __sbrk_heap_end += incr; - - return (void *)prev_heap_end; -} diff --git a/NXP/MIMXRT1064-EVK/app/trng.c b/NXP/MIMXRT1064-EVK/app/trng.c deleted file mode 100644 index 6424f67f..00000000 --- a/NXP/MIMXRT1064-EVK/app/trng.c +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright (c) 2026 Eclipse ThreadX contributors - * - * 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. - */ - -#include "trng.h" -#include "fsl_device_registers.h" -#include "fsl_clock.h" -#include - -#define TRNG_TIMEOUT_CYCLES 1000000UL - -int trng_init(void) -{ - /* Enable TRNG peripheral clock in CCM */ - CLOCK_EnableClock(kCLOCK_Trng); - - /* Check if TRNG is reporting error, clear if needed */ - if (TRNG->MCTL & TRNG_MCTL_ERR_MASK) - { - /* Clear error by resetting to defaults */ - TRNG->MCTL |= TRNG_MCTL_RST_DEF_MASK; - } - - return 0; -} - -int trng_get_random_u32(uint32_t *random_val) -{ - uint32_t timeout = TRNG_TIMEOUT_CYCLES; - - if (!random_val) - { - return -1; - } - - /* Wait for Entropy Valid (ENT_VAL) bit */ - while (!(TRNG->MCTL & TRNG_MCTL_ENT_VAL_MASK)) - { - if (--timeout == 0) - { - return -2; /* Timeout waiting for entropy */ - } - } - - /* Read a 32-bit random word from the first entropy register */ - *random_val = TRNG->ENT[0]; - - return 0; -} - -int trng_get_random_data(void *buffer, size_t length) -{ - uint8_t *out = (uint8_t *)buffer; - size_t offset = 0; - uint32_t rand_word; - int status; - - if (!buffer) - { - return -1; - } - - while (offset < length) - { - status = trng_get_random_u32(&rand_word); - if (status != 0) - { - return status; - } - - size_t chunk = length - offset; - if (chunk > sizeof(uint32_t)) - { - chunk = sizeof(uint32_t); - } - - memcpy(out + offset, &rand_word, chunk); - offset += chunk; - } - - return (int)length; -} diff --git a/NXP/MIMXRT1064-EVK/scripts/fetch_sdk.sh b/NXP/MIMXRT1064-EVK/scripts/fetch_sdk.sh deleted file mode 100644 index 0f2e9b07..00000000 --- a/NXP/MIMXRT1064-EVK/scripts/fetch_sdk.sh +++ /dev/null @@ -1,158 +0,0 @@ -#!/usr/bin/env bash -# Copyright (c) 2026 Eclipse ThreadX contributors -# -# 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. - -set -e - -SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -BOARD_DIR="$(cd "${SCRIPT_DIR}/.." && pwd)" - -LIB_DIR="${BOARD_DIR}/lib/mcux-sdk" -DEVICE_DIR="${LIB_DIR}/devices/MIMXRT1064" -DRIVERS_DIR="${LIB_DIR}/drivers" -UTILITIES_DIR="${LIB_DIR}/utilities" -COMPONENTS_DIR="${LIB_DIR}/components" -BOARD_FILES_DIR="${LIB_DIR}/board" -CMSIS_INCLUDE_DEST="${LIB_DIR}/CMSIS/Include" -APP_STARTUP_DIR="${BOARD_DIR}/app/startup" -TEMP_DIR="${BOARD_DIR}/temp_fetch" - -echo "==========================================" -echo "NXP i.MX RT1064 Standalone Driver Fetcher (POSIX)" -echo "==========================================" -echo "Target Directory: ${LIB_DIR}" -echo "" - -# Clean and recreate directories -rm -rf "${LIB_DIR}" -mkdir -p "${DEVICE_DIR}" -mkdir -p "${DRIVERS_DIR}" -mkdir -p "${UTILITIES_DIR}" -mkdir -p "${COMPONENTS_DIR}/uart" -mkdir -p "${BOARD_FILES_DIR}" -mkdir -p "${CMSIS_INCLUDE_DEST}" -mkdir -p "${APP_STARTUP_DIR}" - -rm -rf "${TEMP_DIR}" -mkdir -p "${TEMP_DIR}" - -clean_temp() { - if [ -d "${TEMP_DIR}" ]; then - rm -rf "${TEMP_DIR}" - fi -} -trap clean_temp EXIT - -# 1. Download official NXP MIMXRT1064 DFP pack from NXP repository -PACK_URL="https://mcuxpresso.nxp.com/cmsis_pack/repo/NXP.MIMXRT1064_DFP.15.1.0.pack" -PACK_ZIP="${TEMP_DIR}/dfp.zip" -PACK_EXTRACT="${TEMP_DIR}/dfp_extracted" - -echo "[INFO] Downloading official NXP MIMXRT1064 Device Pack..." -curl -fsSL "${PACK_URL}" -o "${PACK_ZIP}" - -echo "[INFO] Extracting Device Pack..." -mkdir -p "${PACK_EXTRACT}" -unzip -q "${PACK_ZIP}" -d "${PACK_EXTRACT}" - -# Copy device register headers & system files -for file in MIMXRT1064.h MIMXRT1064_features.h fsl_device_registers.h system_MIMXRT1064.c system_MIMXRT1064.h; do - if [ -f "${PACK_EXTRACT}/${file}" ]; then - cp "${PACK_EXTRACT}/${file}" "${DEVICE_DIR}/" - fi -done - -# Copy core peripheral drivers -for file in fsl_clock.c fsl_clock.h fsl_common.c fsl_common.h fsl_common_arm.c fsl_common_arm.h fsl_gpio.c fsl_gpio.h fsl_lpuart.c fsl_lpuart.h fsl_enet.c fsl_enet.h fsl_iomuxc.h; do - if [ -f "${PACK_EXTRACT}/drivers/${file}" ]; then - cp "${PACK_EXTRACT}/drivers/${file}" "${DRIVERS_DIR}/" - fi -done - -# Copy utilities (debug console & string formatting) -for file in utilities/debug_console_lite/fsl_debug_console.h utilities/debug_console_lite/fsl_debug_console.c utilities/debug_console_lite/fsl_assert.c utilities/debug_console/fsl_debug_console_conf.h utilities/str/fsl_str.c utilities/str/fsl_str.h; do - if [ -f "${PACK_EXTRACT}/${file}" ]; then - cp "${PACK_EXTRACT}/${file}" "${UTILITIES_DIR}/" - fi -done - -# Copy UART component adapter -for file in components/uart/fsl_adapter_uart.h components/uart/fsl_adapter_lpuart.c; do - if [ -f "${PACK_EXTRACT}/${file}" ]; then - cp "${PACK_EXTRACT}/${file}" "${COMPONENTS_DIR}/uart/" - fi -done - -# Copy XIP flexspi boot headers -if [ -d "${PACK_EXTRACT}/xip" ]; then - cp -r "${PACK_EXTRACT}/xip/"* "${DEVICE_DIR}/" -fi -echo "[OK] NXP Device, Driver, Utility, and Component files copied" -echo "" - -# 2. Download EVK-MIMXRT1064 Board Support Files from official NXP mcuxsdk-examples -RAW_BASE="https://raw.githubusercontent.com/nxp-mcuxpresso/mcuxsdk-examples/main/_boards/evkmimxrt1064" -echo "[INFO] Downloading EVK-MIMXRT1064 board support files..." - -curl -fsSL "${RAW_BASE}/board.c" -o "${BOARD_FILES_DIR}/board.c" -curl -fsSL "${RAW_BASE}/board.h" -o "${BOARD_FILES_DIR}/board.h" -curl -fsSL "${RAW_BASE}/project_template/clock_config.c" -o "${BOARD_FILES_DIR}/clock_config.c" -curl -fsSL "${RAW_BASE}/project_template/clock_config.h" -o "${BOARD_FILES_DIR}/clock_config.h" -curl -fsSL "${RAW_BASE}/project_template/pin_mux.c" -o "${BOARD_FILES_DIR}/pin_mux.c" -curl -fsSL "${RAW_BASE}/project_template/pin_mux.h" -o "${BOARD_FILES_DIR}/pin_mux.h" -curl -fsSL "${RAW_BASE}/dcd.c" -o "${BOARD_FILES_DIR}/dcd.c" -curl -fsSL "${RAW_BASE}/dcd.h" -o "${BOARD_FILES_DIR}/dcd.h" -curl -fsSL "${RAW_BASE}/xip/evkmimxrt1064_flexspi_nor_config.c" -o "${BOARD_FILES_DIR}/evkmimxrt1064_flexspi_nor_config.c" -curl -fsSL "${RAW_BASE}/xip/evkmimxrt1064_flexspi_nor_config.h" -o "${BOARD_FILES_DIR}/evkmimxrt1064_flexspi_nor_config.h" - -echo "[INFO] Copying official NXP GNU GCC Linker Script and Startup File into board directory..." -if [ -d "${PACK_EXTRACT}/gcc" ]; then - if [ -f "${PACK_EXTRACT}/gcc/MIMXRT1064xxxxx_flexspi_nor.ld" ]; then - cp "${PACK_EXTRACT}/gcc/MIMXRT1064xxxxx_flexspi_nor.ld" "${BOARD_FILES_DIR}/" - fi - if [ -f "${PACK_EXTRACT}/gcc/startup_MIMXRT1064.S" ]; then - cp "${PACK_EXTRACT}/gcc/startup_MIMXRT1064.S" "${BOARD_FILES_DIR}/" - fi -fi -echo "[OK] Board support and official GCC reference files copied" -echo "" - -# 3. Fetch CMSIS Core headers -echo "[INFO] Cloning CMSIS Core headers (depth=1)..." -CMSIS_CLONE_DIR="${TEMP_DIR}/cmsis_core_repo" -git clone --depth 1 https://github.com/ARM-software/CMSIS_5.git "${CMSIS_CLONE_DIR}" -cp -r "${CMSIS_CLONE_DIR}/CMSIS/Core/Include/"* "${CMSIS_INCLUDE_DEST}/" -echo "[OK] CMSIS Core headers copied" -echo "" - -# 4. Fetch official NXP KSZ8081 PHY driver (100% stock upstream) -echo "[INFO] Downloading official KSZ8081 PHY driver..." -PHY_RAW_BASE="https://raw.githubusercontent.com/eclipse-threadx/getting-started/master/NXP/MIMXRT1060-EVK/lib/MIMXRT1060-evk/src/components/phyksz8081" -mkdir -p "${COMPONENTS_DIR}/phy" -curl --retry 3 -fsSL "${PHY_RAW_BASE}/fsl_phy.c" -o "${COMPONENTS_DIR}/phy/fsl_phy.c" -curl --retry 3 -fsSL "${PHY_RAW_BASE}/fsl_phy.h" -o "${COMPONENTS_DIR}/phy/fsl_phy.h" -echo "[OK] Stock KSZ8081 PHY driver downloaded" -echo "" - -# 5. Fetch official NetX Duo NXP Ethernet driver (100% stock upstream) -echo "[INFO] Downloading official NetX Duo NXP Ethernet driver..." -NETX_RAW_BASE="https://raw.githubusercontent.com/eclipse-threadx/getting-started/master/NXP/MIMXRT1060-EVK/lib/netx_driver" -NETX_DIR="${DRIVERS_DIR}/netx_driver" -mkdir -p "${NETX_DIR}/gnu" -curl --retry 3 -fsSL "${NETX_RAW_BASE}/src/nx_driver_imxrt1062.c" -o "${NETX_DIR}/nx_driver_imxrt1062.c" -curl --retry 3 -fsSL "${NETX_RAW_BASE}/src/nx_driver_imxrt1062.h" -o "${NETX_DIR}/nx_driver_imxrt1062.h" -curl --retry 3 -fsSL "${NETX_RAW_BASE}/src/gnu/nx_driver_imxrt1062_low_level.S" -o "${NETX_DIR}/gnu/nx_driver_imxrt1062_low_level.S" -echo "[OK] Stock NetX Duo NXP Ethernet driver downloaded" -echo "" - -echo "==========================================" -echo "[SUCCESS] NXP i.MX RT1064 drivers successfully fetched!" -echo "==========================================" diff --git a/NXP/MIMXRT1064-EVK/scripts/pydev/flipflop.py b/NXP/MIMXRT1064-EVK/scripts/pydev/flipflop.py deleted file mode 100644 index 17232c27..00000000 --- a/NXP/MIMXRT1064-EVK/scripts/pydev/flipflop.py +++ /dev/null @@ -1,7 +0,0 @@ -if request.IsInit: - lastVal = 0 -else: - lastVal = 1 - lastVal - request.Value = lastVal * 0xFFFFFFFF - -self.NoisyLog("%s on FLIPFLOP at 0x%x, value 0x%x" % (str(request.Type), request.Offset, request.Value)) diff --git a/NXP/MIMXRT1064-EVK/scripts/pydev/ticker.py b/NXP/MIMXRT1064-EVK/scripts/pydev/ticker.py deleted file mode 100644 index 43a27c4e..00000000 --- a/NXP/MIMXRT1064-EVK/scripts/pydev/ticker.py +++ /dev/null @@ -1,16 +0,0 @@ -INIT_VALUE = 1 -STEP = 2 - -if request.IsInit: - lastVal = 0 - step = 1 -elif request.IsUser: - if request.Offset == INIT_VALUE: - lastVal = request.Value - elif request.Offset == STEP: - step = request.Value -else: - lastVal = lastVal + step - request.Value = lastVal - -self.NoisyLog("%s on TICKER at 0x%x, value 0x%x" % (str(request.Type), request.Offset, request.Value)) diff --git a/NXP/MIMXRT1064-EVK/.gitignore b/targets/NXP/MIMXRT1064-EVK/.gitignore similarity index 100% rename from NXP/MIMXRT1064-EVK/.gitignore rename to targets/NXP/MIMXRT1064-EVK/.gitignore diff --git a/NXP/MIMXRT1064-EVK/CMakeLists.txt b/targets/NXP/MIMXRT1064-EVK/CMakeLists.txt similarity index 52% rename from NXP/MIMXRT1064-EVK/CMakeLists.txt rename to targets/NXP/MIMXRT1064-EVK/CMakeLists.txt index 83dad0c1..1e376aa5 100644 --- a/NXP/MIMXRT1064-EVK/CMakeLists.txt +++ b/targets/NXP/MIMXRT1064-EVK/CMakeLists.txt @@ -49,15 +49,46 @@ else() 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 "${CMAKE_CURRENT_LIST_DIR}/../../libs/threadx") +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 "${CMAKE_CURRENT_LIST_DIR}/../../libs/netxduo") +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) @@ -80,156 +111,50 @@ add_library(${SDK_TARGET} OBJECT ${SDK_DIR}/components/uart/fsl_adapter_lpuart.c ) -target_compile_definitions(${SDK_TARGET} +target_link_libraries(${SDK_TARGET} PUBLIC - 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 + mimxrt1064_common ) -target_include_directories(${SDK_TARGET} - PUBLIC - ${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} -) +# 1. Define Board Support Package library +add_subdirectory(lib/bsp) -# 1. Define Board BSP object library -add_library(board_bsp OBJECT - app/startup/startup_mimxrt1064.S - app/startup/tx_initialize_low_level.S - app/board_init.c - app/console.c - app/trng.c - app/sysmem.c - app/syscalls.c -) +# 2. Define NetX Duo driver library targets (cached for networking demos) +add_library(netx_imxrt_driver_common INTERFACE) -target_compile_definitions(board_bsp - PUBLIC - 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(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_include_directories(board_bsp - PUBLIC - ${CMAKE_CURRENT_LIST_DIR}/app - ${SDK_DIR}/CMSIS/Include - ${SDK_DIR}/devices/MIMXRT1064 - ${SDK_DIR}/drivers - ${SDK_DIR}/board - ${SDK_DIR}/utilities - ${SDK_DIR}/components/uart - ${TX_USER_FILE_DIR} +target_compile_options(netx_imxrt_driver_common + INTERFACE + -Wno-unused-variable ) -target_link_libraries(board_bsp - PUBLIC - mcux_sdk +target_link_libraries(netx_imxrt_driver_common + INTERFACE + mimxrt1064_common + netxduo threadx + mcux_sdk ) -# 2. Define NetX Duo driver library targets (cached for networking demos) -add_library(netx_imxrt_driver OBJECT - ${SDK_DIR}/drivers/netx_driver/nx_driver_imxrt1062.c - ${SDK_DIR}/drivers/netx_driver/gnu/nx_driver_imxrt1062_low_level.S - ${SDK_DIR}/components/phy/fsl_phy.c - ${SDK_DIR}/drivers/fsl_enet.c - ) - - target_compile_definitions(netx_imxrt_driver - PUBLIC - 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(netx_imxrt_driver - PUBLIC - ${SDK_DIR}/drivers/netx_driver - ${SDK_DIR}/components/phy - ${CMAKE_CURRENT_LIST_DIR}/app - ${CMAKE_CURRENT_LIST_DIR}/lib/netxduo - ${SDK_DIR}/CMSIS/Include - ${SDK_DIR}/devices/MIMXRT1064 - ${SDK_DIR}/drivers - ${SDK_DIR}/board - ${SDK_DIR}/utilities - ${SDK_DIR}/components/uart - ${TX_USER_FILE_DIR} - ) - - target_link_libraries(netx_imxrt_driver - PUBLIC - netxduo - threadx - mcux_sdk - ) - target_compile_options(netx_imxrt_driver PRIVATE -Wno-unused-variable) - - add_library(netx_imxrt_driver_client OBJECT - ${SDK_DIR}/drivers/netx_driver/nx_driver_imxrt1062.c - ${SDK_DIR}/drivers/netx_driver/gnu/nx_driver_imxrt1062_low_level.S - ${SDK_DIR}/components/phy/fsl_phy.c - ${SDK_DIR}/drivers/fsl_enet.c - ) - - target_compile_definitions(netx_imxrt_driver_client - PUBLIC - NETX_CLIENT_NODE=1 - 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(netx_imxrt_driver_client - PUBLIC - ${SDK_DIR}/drivers/netx_driver - ${SDK_DIR}/components/phy - ${CMAKE_CURRENT_LIST_DIR}/app - ${CMAKE_CURRENT_LIST_DIR}/lib/netxduo - ${SDK_DIR}/CMSIS/Include - ${SDK_DIR}/devices/MIMXRT1064 - ${SDK_DIR}/drivers - ${SDK_DIR}/board - ${SDK_DIR}/utilities - ${SDK_DIR}/components/uart - ${TX_USER_FILE_DIR} - ) - - target_link_libraries(netx_imxrt_driver_client - PUBLIC - netxduo - threadx - mcux_sdk - ) - target_compile_options(netx_imxrt_driver_client PRIVATE -Wno-unused-variable) +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") diff --git a/targets/NXP/MIMXRT1064-EVK/NOTICE.md b/targets/NXP/MIMXRT1064-EVK/NOTICE.md new file mode 100644 index 00000000..2aaba080 --- /dev/null +++ b/targets/NXP/MIMXRT1064-EVK/NOTICE.md @@ -0,0 +1,128 @@ +# Third-Party Software Notices + +This directory contains third-party software components included in the repository as well as build automation scripts and configurations that download and compile external dependencies. This notice lists the licenses and copyrights applicable to those components. + +--- + +## 1. NXP MCUXpresso SDK Drivers, Device Support & Startup Files +* **Source**: https://github.com/nxp-mcuxpresso/mcuxsdk-core / https://github.com/nxp-mcuxpresso/mcuxsdk-examples / https://mcuxpresso.nxp.com +* **Location**: `app/startup/startup_mimxrt1064.S`, `app/startup/MIMXRT1064xxxxx_flexspi_nor.ld`, and `lib/mcux-sdk/` +* **License**: BSD 3-Clause + +```text +Copyright (c) 2015-2016, Freescale Semiconductor, Inc. +Copyright 2018-2025 NXP + +The BSD 3 Clause License + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this +list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its contributors +may be used to endorse or promote products derived from this software without +specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +``` + +--- + +## 2. ARM CMSIS Core +* **Source**: https://github.com/ARM-software/CMSIS_5 +* **Location**: `lib/mcux-sdk/CMSIS/Include/` +* **License**: Apache License 2.0 + +```text +Copyright (c) 2009-2025 Arm Limited. All rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +``` + +--- + +## 3. NetX Duo NXP i.MX RT1062 Ethernet Driver +* **Source**: Eclipse ThreadX getting-started repository (`NXP/MIMXRT1060-EVK/lib/netx_driver`) +* **Location**: `lib/netx_driver/` +* **License**: MIT License +* **Copyright**: Copyright (c) 2024 Microsoft Corporation / Eclipse ThreadX contributors + +```text +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +``` + +--- + +## 4. NXP KSZ8081 PHY Driver +* **Source**: NXP MCUXpresso SDK / Freescale Semiconductor +* **Location**: `lib/phyksz8081/` +* **License**: BSD 3-Clause License +* **Copyright**: Copyright (c) 2015 Freescale Semiconductor, Inc., Copyright 2016-2020 NXP + +```text +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this +list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its contributors +may be used to endorse or promote products derived from this software without +specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +``` diff --git a/targets/NXP/MIMXRT1064-EVK/README.md b/targets/NXP/MIMXRT1064-EVK/README.md new file mode 100644 index 00000000..4023b9ee --- /dev/null +++ b/targets/NXP/MIMXRT1064-EVK/README.md @@ -0,0 +1,266 @@ +# NXP i.MX RT1064-EVK — Eclipse ThreadX & NetX Duo + +Welcome to the board enablement package for running **Eclipse ThreadX RTOS** and **NetX Duo** on the high-performance **NXP i.MX RT1064-EVK** (ARM Cortex-M7 @ 600 MHz). + +This target provides ready demos ranging from fundamental task scheduling and GPIO blinking to full multi-node TCP/IP networking and on-chip hardware cryptographic entropy. +The demos are testable on physical hardware or immediately on your workstation using **Antmicro Renode** system simulation. + +--- + +## Quick Start + +You don't need a physical board to get started! You can fetch dependencies, build all targets, and run the automated test suite in three simple steps: + +### 1. Prerequisites +Ensure you have the following installed on your machine: +* **ARM GNU Toolchain** (`arm-none-eabi-gcc` 10.3+) +* **CMake** (3.20+) and **Ninja** (recommended) or Make +* **Python 3** (3.8+, for automated Renode test runners) +* **Antmicro Renode** (1.15.3+, for simulation) +* **Git** (for repository submodules) + +### 2. Fetch Dependencies & Build +Download the official NXP MCUXpresso SDK drivers and build all demos: + +* **Windows (PowerShell)**: + ```powershell + # 1. Fetch NXP SDK peripheral drivers and CMSIS headers + powershell -ExecutionPolicy Bypass -File .\scripts\fetch_sdk.ps1 + + # 2. Build all demos + powershell -ExecutionPolicy Bypass -File .\scripts\build.ps1 + ``` + +* **Linux / macOS (Bash)**: + ```bash + # 1. Fetch NXP SDK peripheral drivers and CMSIS headers + chmod +x ./scripts/*.sh + ./scripts/fetch_sdk.sh + + # 2. Build all demos + ./scripts/build.sh + ``` + +> [!NOTE] +> The NetX Duo Ethernet driver (`lib/netx_driver`) and KSZ8081 PHY driver (`lib/phyksz8081`) are pre-vendored in this repository. `fetch_sdk` only downloads the official NXP core MCU peripheral drivers and CMSIS headers, verifying every archive against pinned SHA-256 checksums. + +### 3. Run Automated Tests +Verify that all demos build and pass under Renode simulation: +```bash +python ./scripts/test_renode.py --demo threadx_basic +python ./scripts/test_renode.py --demo netx_echo +python ./scripts/test_renode.py --demo netx_trng_console --seed 12345 +``` + +--- + +## Supported Applications + +The build system can compile all demos together (default) or individual demos on demand. Output artifacts are placed in `build/app/demos//`: + +| Application | Architecture | What It Demonstrates | Generated Binaries | +| :--- | :--- | :--- | :--- | +| **`threadx_basic`** | Single-Node | ThreadX kernel fundamentals: preemptive priority scheduling, software timer callbacks, and user LED (`D18`) heartbeat blinking. | `mimxrt1064_threadx.elf`
`mimxrt1064_threadx.bin` | +| **`netx_echo`** | Multi-Node | Full NetX Duo network stack: ARP resolution, ICMP ping replies, UDP datagram echo (port 7), and TCP stream echo (port 7). | `mimxrt1064_threadx.elf` *(Server: 192.168.0.100)*
`mimxrt1064_client.elf` *(Client: 192.168.0.101)* | +| **`netx_trng_console`** | Multi-Node | On-chip hardware True Random Number Generator (`0x400CC000`) integrated with an interactive TCP remote diagnostics management shell (port 23). | `mimxrt1064_threadx.elf` *(Server: 192.168.0.100)*
`mimxrt1064_client.elf` *(Client: 192.168.0.101)* | + +> [!NOTE] +> **How Multi-Node Verification Works**: +> In `netx_echo` and `netx_trng_console`, Renode boots **two independent virtual i.MX RT1064 machines** interconnected via a simulated Ethernet switch. The **server** node runs ThreadX services, while the **client** node runs an automated test suite that transmits network traffic. + +--- + +## Renode Simulation Guide + +Renode provides accurate instruction-level simulation of the ARM Cortex-M7 core and key peripherals, enabling end-to-end verification without hardware. + +### 1. Interactive Simulation (GUI) +Launch Renode with virtual serial terminal windows attached to the microcontroller's UART console: + +* **Windows (PowerShell)**: + ```powershell + # ThreadX Core Basic (single node) + powershell -ExecutionPolicy Bypass -File .\scripts\simulate.ps1 -Demo threadx_basic + + # NetX Duo Network Echo (multi-node server + client) + powershell -ExecutionPolicy Bypass -File .\scripts\simulate.ps1 -Demo netx_echo + + # Hardware TRNG Diagnostic Console (multi-node server + client) + powershell -ExecutionPolicy Bypass -File .\scripts\simulate.ps1 -Demo netx_trng_console + # You can specify a pseudo-random seed for reproducible test runs + powershell -ExecutionPolicy Bypass -File .\scripts\simulate.ps1 -Demo netx_trng_console -Seed 12345 + ``` + +* **Linux / macOS (Bash)**: + ```bash + # ThreadX Core Basic (single node) + ./scripts/simulate.sh -d threadx_basic + + # NetX Duo Network Echo (multi-node server + client) + ./scripts/simulate.sh -d netx_echo + + # Hardware TRNG Diagnostic Console (multi-node server + client) + ./scripts/simulate.sh -d netx_trng_console + # You can specify a pseudo-random seed for reproducible test runs + ./scripts/simulate.sh -d netx_trng_console -s 12345 + ``` + +### 2. Headless Automated Regression Testing (CI/CD) +Headless testing is designed for automated continuous integration pipelines. The runner boots the simulation, monitors the virtual UART logs, and exits with code `0` on success or code `1` on failure/timeout. + +#### Direct Python Runner (Matches CI): +```bash +# Verify ThreadX basic scheduling & timers +python ./scripts/test_renode.py --demo threadx_basic + +# Verify NetX Duo ICMP ping, UDP echo, and TCP echo +python ./scripts/test_renode.py --demo netx_echo + +# Verify Hardware TRNG entropy generation and remote console +python ./scripts/test_renode.py --demo netx_trng_console --seed 12345 +``` + +#### Convenience Shell Wrappers: +* **Windows (PowerShell)**: + ```powershell + powershell -ExecutionPolicy Bypass -File .\scripts\test_headless.ps1 -Demo threadx_basic + powershell -ExecutionPolicy Bypass -File .\scripts\test_headless.ps1 -Demo netx_echo + powershell -ExecutionPolicy Bypass -File .\scripts\test_headless.ps1 -Demo netx_trng_console -Seed 12345 + ``` +* **Linux / macOS (Bash)**: + ```bash + ./scripts/test_headless.sh --demo threadx_basic + ./scripts/test_headless.sh --demo netx_echo + ./scripts/test_headless.sh --demo netx_trng_console --seed 12345 + ``` + +--- + +## Simulation Scope & Hardware Status + +> [!WARNING] +> **Hardware Status: Verified in simulation, not yet on physical silicon.** +> All automated tests in this repository currently run under **Antmicro Renode** system emulation. + +### What Renode Accurately Simulates: +* **Boot & Vector Table**: Boots from simulated FlexSPI NOR Flash into Cortex-M7 privileged mode. +* **ThreadX RTOS Kernel**: Preemptive priority scheduling, thread synchronization (mutexes, semaphores), and software timer ticks. +* **NetX Duo Networking**: Ethernet MAC (`ENET`) DMA transfers, ARP cache handling, ICMP ping replies, UDP socket datagrams, and TCP stream connections. +* **Hardware TRNG Peripheral**: 32-bit entropy generation via on-chip registers at `0x400CC000`. + +### What Renode Stubs: +* **Clock Tree & PLLs**: Renode uses stub tags for the Clock Control Module (`CCM`) and `ANALOG` power blocks. Registers return fixed default values (e.g. `CCM_CBCDR` returns `0x000A8200`), so PLL lock loops succeed unconditionally without exercising analog timing. +* **Core Frequency**: The `600 MHz` banner in the console is a compile-time SDK constant (`SystemCoreClock`), not a measured silicon frequency. +* **Pin Multiplexing**: `IOMUXC` and `IOMUXC_GPR` writes are acknowledged without modeling electrical pin drive strengths or pin collisions. + +--- + +## Target Hardware & Flashing Guide + +If you are flashing to a physical **NXP MIMXRT1064-EVK** board: + +### Hardware Specifications +* **Evaluation Board**: NXP MIMXRT1064-EVK (ARM Cortex-M7 @ up to 600 MHz) +* **Memory**: 4 MB on-chip FlexSPI NOR Flash (`0x70000000`), 1 MB on-chip SRAM (ITCM, DTCM, NonCacheable OCRAM) +* **Serial Console**: LPUART1 via OpenSDA micro-USB (`J41`), 115,200 baud, 8N1 +* **User LED & Button**: Green LED `D18` (`GPIO1_IO09`), SW8 WAKEUP button (`GPIO5_IO00`) +* **Ethernet**: ENET MAC + Microchip KSZ8081RNA PHY via RMII +* **TRNG Hardware**: On-chip True Random Number Generator (`0x400CC000`) + +### Boot Switch Configuration +Set boot switches **SW7** for **Internal Boot (FlexSPI NOR Flash)**: +* `SW7-1`: OFF +* `SW7-2`: ON +* `SW7-3`: OFF +* `SW7-4`: ON + +### Flashing Methods + +#### Option 1: OpenSDA Drag-and-Drop (Fastest) +1. Connect micro-USB cable to `J41` on the EVK board. +2. The board mounts as a USB drive named `RT1064-EVK`. +3. Copy `build/app/demos//mimxrt1064_threadx.bin` and paste it directly onto the drive. +4. The OpenSDA LED blinks rapidly during flashing. Press `SW3` (RESET) to boot. + +#### Option 2: SEGGER J-Link +```text +JLink.exe -device MIMXRT1064xxx6A -if SWD -speed 4000 -autoconnect 1 +loadfile build/app/demos//mimxrt1064_threadx.hex +r +g +``` + +#### Option 3: pyOCD Command Line +```bash +pip install pyocd && pyocd pack install MIMXRT1064 +pyocd flash -t mimxrt1064 build/app/demos//mimxrt1064_threadx.hex +``` + +#### Option 4: NXP MCUXpresso IDE / GUI Flash Tool +1. In MCUXpresso IDE, select **GUI Flash Tool** from the toolbar. +2. Choose target device `MIMXRT1064xxxxA` and memory `PROGRAM_FLASH` (`0x70000000`). +3. Select `build/app/demos//mimxrt1064_threadx.elf` and click **Program**. + +--- + +## Software Architecture & Developer Guide + +### Modular BSP Architecture +The target features a decoupled, three-tier design: +* **`mimxrt1064_bsp`**: Clean C hardware abstraction layer (`bsp/board.h`, `bsp/led.h`, `bsp/console.h`). Application code interacts solely through BSP APIs rather than raw vendor registers. +* **`board_bsp`**: Startup assembly (`startup_mimxrt1064.S`), low-level ThreadX initialization (`tx_initialize_low_level.S`), newlib standard C library syscalls (`_sbrk` heap protection), and hardware TRNG drivers. +* **`mimxrt1064_common`**: Central CMake `INTERFACE` library propagating required MCU compiler definitions (`CPU_MIMXRT1064DVL6A`, `XIP_EXTERNAL_FLASH=1`, etc.) and SDK include directories to all targets automatically. + +### Adding a Custom Demo in 4 Steps + +#### Step 1: Create the Demo Directory +Create a folder under `app/demos/` (e.g., `app/demos/my_new_demo/`). + +#### Step 2: Write Application Code (`main.c`) +```c +#include "bsp/board.h" +#include "bsp/led.h" +#include "bsp/console.h" +#include "tx_api.h" + +int main(void) +{ + /* Initialize MPU, system clocks, pins, LED, and console */ + bsp_board_init(); + + /* Enter ThreadX RTOS Kernel */ + tx_kernel_enter(); + return 0; +} +``` + +#### Step 3: Create `CMakeLists.txt` +Thanks to CMake target inheritance, you only need to link `board_bsp`, `threadx`, and `mcux_sdk` — all compiler definitions and SDK include paths are inherited automatically: +```cmake +set(DEMO_TARGET "demo_my_new_demo") +add_executable(${DEMO_TARGET} main.c) +set_target_properties(${DEMO_TARGET} PROPERTIES OUTPUT_NAME "mimxrt1064_threadx") + +# Only private demo includes are needed; SDK headers and board definitions +# are inherited automatically from board_bsp. +target_include_directories(${DEMO_TARGET} PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} +) + +target_link_libraries(${DEMO_TARGET} PRIVATE + board_bsp + threadx + mcux_sdk + # netxduo # Uncomment if using network stack + # netx_imxrt_driver # Uncomment if using network driver +) + +set_target_linker(${DEMO_TARGET} "${CMAKE_CURRENT_SOURCE_DIR}/../../startup/MIMXRT1064xxxxx_flexspi_nor.ld") +post_build(${DEMO_TARGET}) +``` + +#### Step 4: Build and Simulate +```bash +cmake -B build -G Ninja -DACTIVE_DEMO=my_new_demo +cmake --build build +``` diff --git a/NXP/MIMXRT1064-EVK/app/MIMXRT1062.h b/targets/NXP/MIMXRT1064-EVK/app/MIMXRT1062.h similarity index 91% rename from NXP/MIMXRT1064-EVK/app/MIMXRT1062.h rename to targets/NXP/MIMXRT1064-EVK/app/MIMXRT1062.h index fcfe2f66..344898f4 100644 --- a/NXP/MIMXRT1064-EVK/app/MIMXRT1062.h +++ b/targets/NXP/MIMXRT1064-EVK/app/MIMXRT1062.h @@ -15,8 +15,8 @@ * Compatibility header: redirects MIMXRT1062.h from stock NetX Duo driver * to MIMXRT1064 device registers without modifying vendor source files. */ -#ifndef _MIMXRT1062_H_ -#define _MIMXRT1062_H_ +#ifndef MIMXRT1062_H +#define MIMXRT1062_H #include "fsl_device_registers.h" @@ -30,4 +30,4 @@ #define NX_DRIVER_ETHERNET_MAC {0x02, 0x11, 0x22, 0x33, 0x44, 0x52} #endif -#endif /* _MIMXRT1062_H_ */ +#endif /* MIMXRT1062_H */ diff --git a/NXP/MIMXRT1064-EVK/app/ansi_colors.h b/targets/NXP/MIMXRT1064-EVK/app/ansi_colors.h similarity index 100% rename from NXP/MIMXRT1064-EVK/app/ansi_colors.h rename to targets/NXP/MIMXRT1064-EVK/app/ansi_colors.h diff --git a/NXP/MIMXRT1064-EVK/app/demos/netx_echo/CMakeLists.txt b/targets/NXP/MIMXRT1064-EVK/app/demos/netx_echo/CMakeLists.txt similarity index 59% rename from NXP/MIMXRT1064-EVK/app/demos/netx_echo/CMakeLists.txt rename to targets/NXP/MIMXRT1064-EVK/app/demos/netx_echo/CMakeLists.txt index 9aa97bf7..f060bf47 100644 --- a/NXP/MIMXRT1064-EVK/app/demos/netx_echo/CMakeLists.txt +++ b/targets/NXP/MIMXRT1064-EVK/app/demos/netx_echo/CMakeLists.txt @@ -16,33 +16,10 @@ add_executable(${SERVER_TARGET} ) set_target_properties(${SERVER_TARGET} PROPERTIES OUTPUT_NAME "mimxrt1064_threadx") -# Set compile definitions for server -target_compile_definitions(${SERVER_TARGET} - PRIVATE - 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 -) - # Include paths for server target_include_directories(${SERVER_TARGET} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} - ${CMAKE_CURRENT_SOURCE_DIR}/../.. - ${SDK_DIR}/drivers/netx_driver - ${SDK_DIR}/CMSIS/Include - ${SDK_DIR}/devices/MIMXRT1064 - ${SDK_DIR}/drivers - ${SDK_DIR}/board - ${SDK_DIR}/utilities - ${SDK_DIR}/components/uart - ${SDK_DIR}/components/phy - ${TX_USER_FILE_DIR} ) # Link libraries for server @@ -70,30 +47,12 @@ set_target_properties(${CLIENT_TARGET} PROPERTIES OUTPUT_NAME "mimxrt1064_client target_compile_definitions(${CLIENT_TARGET} PRIVATE NETX_CLIENT_NODE=1 - 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 ) # Include paths for client target_include_directories(${CLIENT_TARGET} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} - ${CMAKE_CURRENT_SOURCE_DIR}/../.. - ${SDK_DIR}/drivers/netx_driver - ${SDK_DIR}/CMSIS/Include - ${SDK_DIR}/devices/MIMXRT1064 - ${SDK_DIR}/drivers - ${SDK_DIR}/board - ${SDK_DIR}/utilities - ${SDK_DIR}/components/uart - ${SDK_DIR}/components/phy - ${TX_USER_FILE_DIR} ) # Link libraries for client diff --git a/NXP/MIMXRT1064-EVK/app/demos/netx_echo/client_main.c b/targets/NXP/MIMXRT1064-EVK/app/demos/netx_echo/client_main.c similarity index 76% rename from NXP/MIMXRT1064-EVK/app/demos/netx_echo/client_main.c rename to targets/NXP/MIMXRT1064-EVK/app/demos/netx_echo/client_main.c index a9032e6e..483bcb18 100644 --- a/NXP/MIMXRT1064-EVK/app/demos/netx_echo/client_main.c +++ b/targets/NXP/MIMXRT1064-EVK/app/demos/netx_echo/client_main.c @@ -11,13 +11,17 @@ * Ali Eissa - 2026 version. */ -#include "board_init.h" -#include "console.h" +#include +#include +#include +#include +#include "bsp/board.h" +#include "bsp/led.h" +#include "bsp/console.h" +#include "board_config.h" #include "tx_api.h" #include "nx_api.h" #include "ansi_colors.h" -#include -#include #define DEMO_STACK_SIZE 2048 #define PACKET_SIZE 1536 @@ -32,9 +36,9 @@ #define GATEWAY_ADDRESS_VAL IP_ADDRESS(192, 168, 0, 1) static TX_THREAD client_thread; -static uint8_t client_thread_stack[DEMO_STACK_SIZE]; +static ULONG client_thread_stack[DEMO_STACK_SIZE / sizeof(ULONG)]; -static uint8_t ip_thread_stack[DEMO_STACK_SIZE]; +static ULONG ip_thread_stack[DEMO_STACK_SIZE / sizeof(ULONG)]; static uint8_t arp_cache_area[ARP_CACHE_SIZE]; static NX_PACKET_POOL client_pool; @@ -51,8 +55,8 @@ static void client_thread_entry(ULONG thread_input); int main(void) { - /* Initialize MPU, system clocks (600 MHz), pins, LED GPIO, console, and ENET pins */ - board_init(); + /* Initialize hardware via BSP interface */ + bsp_board_init(); printf(ANSI_BOLD ANSI_CYAN "\r\n==================================================\r\n" ANSI_RESET); printf(ANSI_BOLD ANSI_CYAN " Eclipse ThreadX & NetX Duo on NXP i.MX RT1064-EVK\r\n" ANSI_RESET); @@ -206,22 +210,40 @@ static void client_thread_entry(ULONG thread_input) if (nx_packet_allocate(&client_pool, &tx_packet, NX_UDP_PACKET, TX_WAIT_FOREVER) == NX_SUCCESS) { const char *udp_payload = "Hello ThreadX UDP Echo!"; - nx_packet_data_append(tx_packet, (VOID *)udp_payload, strlen(udp_payload), &client_pool, TX_WAIT_FOREVER); - printf(TAG_CLIENT " " MSG_INFO "Sent UDP payload: '%s'\r\n" ANSI_RESET, udp_payload); - nx_udp_socket_send(&udp_client_socket, tx_packet, SERVER_IP_ADDRESS, ECHO_SERVER_PORT); - - NX_PACKET *rx_packet = NX_NULL; - status = nx_udp_socket_receive(&udp_client_socket, &rx_packet, 200); - if (status == NX_SUCCESS && rx_packet != NX_NULL) + status = nx_packet_data_append(tx_packet, (VOID *)udp_payload, strlen(udp_payload), &client_pool, TX_WAIT_FOREVER); + if (status == NX_SUCCESS) { - printf(TAG_CLIENT " " MSG_SUCCESS "[PASS] Received UDP Echo: '%.*s' (%lu bytes)\r\n" ANSI_RESET, - (int)rx_packet->nx_packet_length, rx_packet->nx_packet_prepend_ptr, rx_packet->nx_packet_length); - nx_packet_release(rx_packet); - test_udp_passed = 1; + printf(TAG_CLIENT " " MSG_INFO "Sent UDP payload: '%s'\r\n" ANSI_RESET, udp_payload); + status = nx_udp_socket_send(&udp_client_socket, tx_packet, SERVER_IP_ADDRESS, ECHO_SERVER_PORT); + } + if (status != NX_SUCCESS) + { + nx_packet_release(tx_packet); + printf(TAG_CLIENT " " MSG_ERROR "[FAIL] Failed to send UDP packet: 0x%02X\r\n" ANSI_RESET, status); } else { - printf(TAG_CLIENT " " MSG_ERROR "[FAIL] UDP Echo receive timed out or failed: 0x%02X\r\n" ANSI_RESET, status); + NX_PACKET *rx_packet = NX_NULL; + status = nx_udp_socket_receive(&udp_client_socket, &rx_packet, 200); + if (status == NX_SUCCESS && rx_packet != NX_NULL) + { + CHAR rx_buf[128]; + ULONG bytes_copied = 0; + nx_packet_data_retrieve(rx_packet, rx_buf, &bytes_copied); + if (bytes_copied >= sizeof(rx_buf)) + { + bytes_copied = sizeof(rx_buf) - 1; + } + rx_buf[bytes_copied] = '\0'; + printf(TAG_CLIENT " " MSG_SUCCESS "[PASS] Received UDP Echo: '%s' (%lu bytes)\r\n" ANSI_RESET, + rx_buf, bytes_copied); + nx_packet_release(rx_packet); + test_udp_passed = 1; + } + else + { + printf(TAG_CLIENT " " MSG_ERROR "[FAIL] UDP Echo receive timed out or failed: 0x%02X\r\n" ANSI_RESET, status); + } } } nx_udp_socket_unbind(&udp_client_socket); @@ -257,22 +279,40 @@ static void client_thread_entry(ULONG thread_input) if (nx_packet_allocate(&client_pool, &tx_packet, NX_TCP_PACKET, TX_WAIT_FOREVER) == NX_SUCCESS) { const char *tcp_payload = "Hello ThreadX TCP Echo!"; - nx_packet_data_append(tx_packet, (VOID *)tcp_payload, strlen(tcp_payload), &client_pool, TX_WAIT_FOREVER); - printf(TAG_CLIENT " " MSG_INFO "Sent TCP payload: '%s'\r\n" ANSI_RESET, tcp_payload); - nx_tcp_socket_send(&tcp_client_socket, tx_packet, 200); - - NX_PACKET *rx_packet = NX_NULL; - status = nx_tcp_socket_receive(&tcp_client_socket, &rx_packet, 200); - if (status == NX_SUCCESS && rx_packet != NX_NULL) + status = nx_packet_data_append(tx_packet, (VOID *)tcp_payload, strlen(tcp_payload), &client_pool, TX_WAIT_FOREVER); + if (status == NX_SUCCESS) { - printf(TAG_CLIENT " " MSG_SUCCESS "[PASS] Received TCP Echo: '%.*s' (%lu bytes)\r\n" ANSI_RESET, - (int)rx_packet->nx_packet_length, rx_packet->nx_packet_prepend_ptr, rx_packet->nx_packet_length); - nx_packet_release(rx_packet); - test_tcp_passed = 1; + printf(TAG_CLIENT " " MSG_INFO "Sent TCP payload: '%s'\r\n" ANSI_RESET, tcp_payload); + status = nx_tcp_socket_send(&tcp_client_socket, tx_packet, 200); + } + if (status != NX_SUCCESS) + { + nx_packet_release(tx_packet); + printf(TAG_CLIENT " " MSG_ERROR "[FAIL] Failed to send TCP packet: 0x%02X\r\n" ANSI_RESET, status); } else { - printf(TAG_CLIENT " " MSG_ERROR "[FAIL] TCP Echo receive timed out or failed: 0x%02X\r\n" ANSI_RESET, status); + NX_PACKET *rx_packet = NX_NULL; + status = nx_tcp_socket_receive(&tcp_client_socket, &rx_packet, 200); + if (status == NX_SUCCESS && rx_packet != NX_NULL) + { + CHAR rx_buf[128]; + ULONG bytes_copied = 0; + nx_packet_data_retrieve(rx_packet, rx_buf, &bytes_copied); + if (bytes_copied >= sizeof(rx_buf)) + { + bytes_copied = sizeof(rx_buf) - 1; + } + rx_buf[bytes_copied] = '\0'; + printf(TAG_CLIENT " " MSG_SUCCESS "[PASS] Received TCP Echo: '%s' (%lu bytes)\r\n" ANSI_RESET, + rx_buf, bytes_copied); + nx_packet_release(rx_packet); + test_tcp_passed = 1; + } + else + { + printf(TAG_CLIENT " " MSG_ERROR "[FAIL] TCP Echo receive timed out or failed: 0x%02X\r\n" ANSI_RESET, status); + } } } nx_tcp_socket_disconnect(&tcp_client_socket, 100); @@ -314,6 +354,6 @@ static void client_thread_entry(ULONG thread_input) while (1) { tx_thread_sleep(50); - USER_LED_TOGGLE(); + bsp_led_toggle(); } } diff --git a/NXP/MIMXRT1064-EVK/app/demos/netx_echo/main.c b/targets/NXP/MIMXRT1064-EVK/app/demos/netx_echo/main.c similarity index 82% rename from NXP/MIMXRT1064-EVK/app/demos/netx_echo/main.c rename to targets/NXP/MIMXRT1064-EVK/app/demos/netx_echo/main.c index 0e9fff45..b77f521e 100644 --- a/NXP/MIMXRT1064-EVK/app/demos/netx_echo/main.c +++ b/targets/NXP/MIMXRT1064-EVK/app/demos/netx_echo/main.c @@ -11,12 +11,16 @@ * Ali Eissa - 2026 version. */ -#include "board_init.h" -#include "console.h" +#include +#include +#include +#include "bsp/board.h" +#include "bsp/led.h" +#include "bsp/console.h" +#include "board_config.h" #include "tx_api.h" #include "nx_api.h" #include "ansi_colors.h" -#include #define DEMO_STACK_SIZE 2048 #define PACKET_SIZE 1536 @@ -30,15 +34,15 @@ #define GATEWAY_ADDRESS_VAL IP_ADDRESS(192, 168, 0, 1) static TX_THREAD monitor_thread; -static uint8_t monitor_thread_stack[DEMO_STACK_SIZE]; +static ULONG monitor_thread_stack[DEMO_STACK_SIZE / sizeof(ULONG)]; static TX_THREAD udp_echo_thread; -static uint8_t udp_echo_thread_stack[DEMO_STACK_SIZE]; +static ULONG udp_echo_thread_stack[DEMO_STACK_SIZE / sizeof(ULONG)]; static TX_THREAD tcp_echo_thread; -static uint8_t tcp_echo_thread_stack[DEMO_STACK_SIZE]; +static ULONG tcp_echo_thread_stack[DEMO_STACK_SIZE / sizeof(ULONG)]; -static uint8_t ip_thread_stack[DEMO_STACK_SIZE]; +static ULONG ip_thread_stack[DEMO_STACK_SIZE / sizeof(ULONG)]; static uint8_t arp_cache_area[ARP_CACHE_SIZE]; static NX_PACKET_POOL pool_0; @@ -57,8 +61,8 @@ static void tcp_echo_thread_entry(ULONG thread_input); int main(void) { - /* Initialize MPU, system clocks (600 MHz), pins, LED GPIO, console, and ENET pins */ - board_init(); + /* Initialize hardware via BSP interface */ + bsp_board_init(); printf(ANSI_BOLD ANSI_CYAN "\r\n==================================================\r\n" ANSI_RESET); printf(ANSI_BOLD ANSI_CYAN " Eclipse ThreadX & NetX Duo on NXP i.MX RT1064-EVK\r\n" ANSI_RESET); @@ -190,7 +194,7 @@ static void monitor_thread_entry(ULONG thread_input) tx_thread_sleep(50); /* Toggle User LED to indicate active heartbeat */ - USER_LED_TOGGLE(); + bsp_led_toggle(); led_state = !led_state; } } @@ -239,9 +243,25 @@ static void udp_echo_thread_entry(ULONG thread_input) NX_PACKET *tx_packet = NX_NULL; if (nx_packet_allocate(&pool_0, &tx_packet, NX_UDP_PACKET, TX_NO_WAIT) == NX_SUCCESS) { - nx_packet_data_append(tx_packet, rx_packet->nx_packet_prepend_ptr, - rx_packet->nx_packet_length, &pool_0, TX_NO_WAIT); - nx_udp_socket_send(&udp_socket, tx_packet, peer_ip, peer_port); + CHAR echo_buf[512]; + ULONG bytes_copied = 0; + if (rx_packet->nx_packet_length <= sizeof(echo_buf) && + nx_packet_data_retrieve(rx_packet, echo_buf, &bytes_copied) == NX_SUCCESS) + { + status = nx_packet_data_append(tx_packet, echo_buf, bytes_copied, &pool_0, TX_NO_WAIT); + if (status == NX_SUCCESS) + { + status = nx_udp_socket_send(&udp_socket, tx_packet, peer_ip, peer_port); + } + if (status != NX_SUCCESS) + { + nx_packet_release(tx_packet); + } + } + else + { + nx_packet_release(tx_packet); + } } /* Release the received packet */ @@ -290,9 +310,25 @@ static void tcp_echo_thread_entry(ULONG thread_input) NX_PACKET *tx_packet = NX_NULL; if (nx_packet_allocate(&pool_0, &tx_packet, NX_TCP_PACKET, TX_WAIT_FOREVER) == NX_SUCCESS) { - nx_packet_data_append(tx_packet, packet_ptr->nx_packet_prepend_ptr, - packet_ptr->nx_packet_length, &pool_0, TX_WAIT_FOREVER); - nx_tcp_socket_send(&echo_socket, tx_packet, NX_WAIT_FOREVER); + CHAR echo_buf[512]; + ULONG bytes_copied = 0; + if (packet_ptr->nx_packet_length <= sizeof(echo_buf) && + nx_packet_data_retrieve(packet_ptr, echo_buf, &bytes_copied) == NX_SUCCESS) + { + status = nx_packet_data_append(tx_packet, echo_buf, bytes_copied, &pool_0, TX_WAIT_FOREVER); + if (status == NX_SUCCESS) + { + status = nx_tcp_socket_send(&echo_socket, tx_packet, TX_WAIT_FOREVER); + } + if (status != NX_SUCCESS) + { + nx_packet_release(tx_packet); + } + } + else + { + nx_packet_release(tx_packet); + } } nx_packet_release(packet_ptr); } diff --git a/NXP/MIMXRT1064-EVK/app/demos/netx_echo/test_echo.ps1 b/targets/NXP/MIMXRT1064-EVK/app/demos/netx_echo/test_echo.ps1 similarity index 100% rename from NXP/MIMXRT1064-EVK/app/demos/netx_echo/test_echo.ps1 rename to targets/NXP/MIMXRT1064-EVK/app/demos/netx_echo/test_echo.ps1 diff --git a/NXP/MIMXRT1064-EVK/app/demos/netx_echo/test_echo.sh b/targets/NXP/MIMXRT1064-EVK/app/demos/netx_echo/test_echo.sh similarity index 100% rename from NXP/MIMXRT1064-EVK/app/demos/netx_echo/test_echo.sh rename to targets/NXP/MIMXRT1064-EVK/app/demos/netx_echo/test_echo.sh diff --git a/NXP/MIMXRT1064-EVK/app/demos/netx_trng_console/CMakeLists.txt b/targets/NXP/MIMXRT1064-EVK/app/demos/netx_trng_console/CMakeLists.txt similarity index 59% rename from NXP/MIMXRT1064-EVK/app/demos/netx_trng_console/CMakeLists.txt rename to targets/NXP/MIMXRT1064-EVK/app/demos/netx_trng_console/CMakeLists.txt index d8fc8cab..14c28d2f 100644 --- a/NXP/MIMXRT1064-EVK/app/demos/netx_trng_console/CMakeLists.txt +++ b/targets/NXP/MIMXRT1064-EVK/app/demos/netx_trng_console/CMakeLists.txt @@ -16,33 +16,10 @@ add_executable(${SERVER_TARGET} ) set_target_properties(${SERVER_TARGET} PROPERTIES OUTPUT_NAME "mimxrt1064_threadx") -# Set compile definitions for server -target_compile_definitions(${SERVER_TARGET} - PRIVATE - 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 -) - # Include paths for server target_include_directories(${SERVER_TARGET} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} - ${CMAKE_CURRENT_SOURCE_DIR}/../.. - ${SDK_DIR}/drivers/netx_driver - ${SDK_DIR}/CMSIS/Include - ${SDK_DIR}/devices/MIMXRT1064 - ${SDK_DIR}/drivers - ${SDK_DIR}/board - ${SDK_DIR}/utilities - ${SDK_DIR}/components/uart - ${SDK_DIR}/components/phy - ${TX_USER_FILE_DIR} ) # Link libraries for server @@ -70,30 +47,12 @@ set_target_properties(${CLIENT_TARGET} PROPERTIES OUTPUT_NAME "mimxrt1064_client target_compile_definitions(${CLIENT_TARGET} PRIVATE NETX_CLIENT_NODE=1 - 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 ) # Include paths for client target_include_directories(${CLIENT_TARGET} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} - ${CMAKE_CURRENT_SOURCE_DIR}/../.. - ${SDK_DIR}/drivers/netx_driver - ${SDK_DIR}/CMSIS/Include - ${SDK_DIR}/devices/MIMXRT1064 - ${SDK_DIR}/drivers - ${SDK_DIR}/board - ${SDK_DIR}/utilities - ${SDK_DIR}/components/uart - ${SDK_DIR}/components/phy - ${TX_USER_FILE_DIR} ) # Link libraries for client diff --git a/NXP/MIMXRT1064-EVK/app/demos/netx_trng_console/client_main.c b/targets/NXP/MIMXRT1064-EVK/app/demos/netx_trng_console/client_main.c similarity index 75% rename from NXP/MIMXRT1064-EVK/app/demos/netx_trng_console/client_main.c rename to targets/NXP/MIMXRT1064-EVK/app/demos/netx_trng_console/client_main.c index f95fff17..048bc25f 100644 --- a/NXP/MIMXRT1064-EVK/app/demos/netx_trng_console/client_main.c +++ b/targets/NXP/MIMXRT1064-EVK/app/demos/netx_trng_console/client_main.c @@ -11,13 +11,17 @@ * Ali Eissa - 2026 version. */ -#include "board_init.h" -#include "console.h" +#include +#include +#include +#include +#include "bsp/board.h" +#include "bsp/led.h" +#include "bsp/console.h" +#include "board_config.h" #include "ansi_colors.h" #include "tx_api.h" #include "nx_api.h" -#include -#include #define DEMO_STACK_SIZE 2048 #define PACKET_SIZE 1536 @@ -48,7 +52,7 @@ static void client_test_thread_entry(ULONG thread_input); int main(void) { - board_init(); + bsp_board_init(); printf(ANSI_BOLD ANSI_YELLOW "\r\n==================================================\r\n" ANSI_RESET); printf(ANSI_BOLD ANSI_YELLOW " MIMXRT1064 TRNG & Console Verification Client\r\n" ANSI_RESET); @@ -106,19 +110,35 @@ static UINT send_and_receive(NX_TCP_SOCKET *socket, const char *cmd, char *rx_bu UINT status; status = nx_packet_allocate(&client_pool, &tx_packet, NX_TCP_PACKET, TX_WAIT_FOREVER); - if (status != NX_SUCCESS) return status; + if (status != NX_SUCCESS) + { + return status; + } + + status = nx_packet_data_append(tx_packet, (VOID *)cmd, strlen(cmd), &client_pool, TX_WAIT_FOREVER); + if (status != NX_SUCCESS) + { + nx_packet_release(tx_packet); + return status; + } - nx_packet_data_append(tx_packet, (VOID *)cmd, strlen(cmd), &client_pool, TX_WAIT_FOREVER); status = nx_tcp_socket_send(socket, tx_packet, TX_WAIT_FOREVER); - if (status != NX_SUCCESS) return status; + if (status != NX_SUCCESS) + { + nx_packet_release(tx_packet); + return status; + } status = nx_tcp_socket_receive(socket, &rx_packet, timeout); if (status == NX_SUCCESS && rx_packet != NX_NULL) { - ULONG len = rx_packet->nx_packet_length; - if (len >= rx_buf_size) len = rx_buf_size - 1; - memcpy(rx_buf, rx_packet->nx_packet_prepend_ptr, len); - rx_buf[len] = '\0'; + ULONG bytes_copied = 0; + nx_packet_data_retrieve(rx_packet, rx_buf, &bytes_copied); + if (bytes_copied >= rx_buf_size) + { + bytes_copied = rx_buf_size - 1; + } + rx_buf[bytes_copied] = '\0'; nx_packet_release(rx_packet); } return status; @@ -193,13 +213,50 @@ static void client_test_thread_entry(ULONG thread_input) printf("\r\n" TAG_CLIENT " [Test 3/5] Querying on-chip TRNG entropy ('trng')...\r\n"); memset(buffer, 0, sizeof(buffer)); status = send_and_receive(&client_socket, "trng\r\n", buffer, sizeof(buffer), 200); - if (status == NX_SUCCESS && strstr(buffer, "[TRNG] Hardware Entropy:")) + + char *entropy_str = (status == NX_SUCCESS) ? strstr(buffer, "[TRNG] Hardware Entropy:") : NX_NULL; + if (entropy_str != NX_NULL) { - printf(TAG_CLIENT " " MSG_SUCCESS " Hardware TRNG Entropy Received:\r\n %s", buffer); + const char *vals_str = entropy_str + strlen("[TRNG] Hardware Entropy:"); + unsigned long w1 = 0, w2 = 0, w3 = 0, w4 = 0; + int parsed = sscanf(vals_str, "%lx %lx %lx %lx", &w1, &w2, &w3, &w4); + + if (parsed != 4) + { + printf(TAG_CLIENT " " MSG_ERROR " Assertion failed: Expected 4 entropy words, parsed %d\r\n", parsed); + all_passed = 0; + } + else if (w1 == 0 && w2 == 0 && w3 == 0 && w4 == 0) + { + printf(TAG_CLIENT " " MSG_ERROR " Assertion failed: All 4 entropy words are zero (0x00000000)\r\n"); + all_passed = 0; + } + else if (w1 == w2 || w1 == w3 || w1 == w4 || w2 == w3 || w2 == w4 || w3 == w4) + { + printf(TAG_CLIENT " " MSG_ERROR " Assertion failed: Entropy words are not distinct (0x%08lX 0x%08lX 0x%08lX 0x%08lX)\r\n", + w1, w2, w3, w4); + all_passed = 0; + } + else + { + printf(TAG_CLIENT " " MSG_SUCCESS " Hardware TRNG Entropy Received:\r\n %s", buffer); + printf(TAG_CLIENT " " MSG_SUCCESS " Entropy words verified: 4 words parsed, non-zero, all mutually distinct.\r\n"); + + /* Verify exact sequence under deterministic Renode simulation (seed 12345) */ + const unsigned long seed_12345_w1 = 0x69D43FF3UL; + const unsigned long seed_12345_w2 = 0x54E900EEUL; + const unsigned long seed_12345_w3 = 0x2514F462UL; + const unsigned long seed_12345_w4 = 0x39F5B5D8UL; + + if (w1 == seed_12345_w1 && w2 == seed_12345_w2 && w3 == seed_12345_w3 && w4 == seed_12345_w4) + { + printf(TAG_CLIENT " " MSG_SUCCESS " Deterministic seed (12345) PRNG sequence verified exactly!\r\n"); + } + } } else { - printf(TAG_CLIENT " " MSG_ERROR " TRNG query failed (status: 0x%02X)\r\n", status); + printf(TAG_CLIENT " " MSG_ERROR " TRNG query failed (status: 0x%02X, response: '%s')\r\n", status, buffer); all_passed = 0; } diff --git a/NXP/MIMXRT1064-EVK/app/demos/netx_trng_console/main.c b/targets/NXP/MIMXRT1064-EVK/app/demos/netx_trng_console/main.c similarity index 80% rename from NXP/MIMXRT1064-EVK/app/demos/netx_trng_console/main.c rename to targets/NXP/MIMXRT1064-EVK/app/demos/netx_trng_console/main.c index b107371b..cba21c29 100644 --- a/NXP/MIMXRT1064-EVK/app/demos/netx_trng_console/main.c +++ b/targets/NXP/MIMXRT1064-EVK/app/demos/netx_trng_console/main.c @@ -11,14 +11,18 @@ * Ali Eissa - 2026 version. */ -#include "board_init.h" -#include "console.h" +#include +#include +#include +#include +#include "bsp/board.h" +#include "bsp/led.h" +#include "bsp/console.h" +#include "board_config.h" #include "ansi_colors.h" #include "trng.h" #include "tx_api.h" #include "nx_api.h" -#include -#include #define DEMO_STACK_SIZE 2048 #define PACKET_SIZE 1536 @@ -57,8 +61,8 @@ static void shell_thread_entry(ULONG thread_input); int main(void) { - /* Initialize MPU, clocks (600 MHz), pins, LED GPIO, console, and ENET */ - board_init(); + /* Initialize hardware via BSP interface */ + bsp_board_init(); /* Initialize on-chip Hardware TRNG */ trng_init(); @@ -175,7 +179,7 @@ static void heartbeat_thread_entry(ULONG thread_input) while (1) { tx_thread_sleep(50); - USER_LED_TOGGLE(); + bsp_led_toggle(); } } @@ -186,10 +190,23 @@ static void send_tcp_response(NX_TCP_SOCKET *socket, const char *msg) size_t len = strlen(msg); status = nx_packet_allocate(&pool_0, &tx_packet, NX_TCP_PACKET, TX_WAIT_FOREVER); - if (status == NX_SUCCESS) + if (status != NX_SUCCESS) + { + return; + } + + status = nx_packet_data_append(tx_packet, (VOID *)msg, len, &pool_0, TX_WAIT_FOREVER); + if (status != NX_SUCCESS) + { + nx_packet_release(tx_packet); + return; + } + + status = nx_tcp_socket_send(socket, tx_packet, 200); + if (status != NX_SUCCESS) { - nx_packet_data_append(tx_packet, (VOID *)msg, len, &pool_0, TX_WAIT_FOREVER); - nx_tcp_socket_send(socket, tx_packet, TX_WAIT_FOREVER); + /* In NetX Duo, a failed send leaves packet ownership with the caller */ + nx_packet_release(tx_packet); } } @@ -251,20 +268,28 @@ static void shell_thread_entry(ULONG thread_input) break; } - ULONG copy_len = packet_ptr->nx_packet_length; - if (copy_len >= sizeof(line_buffer)) + ULONG bytes_copied = 0; + status = nx_packet_data_retrieve(packet_ptr, line_buffer, &bytes_copied); + nx_packet_release(packet_ptr); + + if (status != NX_SUCCESS && bytes_copied == 0) { - copy_len = sizeof(line_buffer) - 1; + continue; } - memcpy(line_buffer, packet_ptr->nx_packet_prepend_ptr, copy_len); - line_buffer[copy_len] = '\0'; - nx_packet_release(packet_ptr); - /* Trim trailing CRLF */ - char *p = line_buffer + strlen(line_buffer) - 1; - while (p >= line_buffer && (*p == '\r' || *p == '\n' || *p == ' ')) + if (bytes_copied >= sizeof(line_buffer)) + { + bytes_copied = sizeof(line_buffer) - 1; + } + line_buffer[bytes_copied] = '\0'; + + /* Safe trimming of trailing CRLF and spaces without pointer underflow */ + size_t len = strlen(line_buffer); + while (len > 0 && (line_buffer[len - 1] == '\r' || + line_buffer[len - 1] == '\n' || + line_buffer[len - 1] == ' ')) { - *p-- = '\0'; + line_buffer[--len] = '\0'; } if (strlen(line_buffer) == 0) @@ -288,17 +313,29 @@ static void shell_thread_entry(ULONG thread_input) else if (strcmp(line_buffer, "trng") == 0 || strcmp(line_buffer, "rand") == 0) { uint32_t r1 = 0, r2 = 0, r3 = 0, r4 = 0; - trng_get_random_u32(&r1); - trng_get_random_u32(&r2); - trng_get_random_u32(&r3); - trng_get_random_u32(&r4); + int s1 = trng_get_random_u32(&r1); + int s2 = trng_get_random_u32(&r2); + int s3 = trng_get_random_u32(&r3); + int s4 = trng_get_random_u32(&r4); - snprintf(resp_buffer, sizeof(resp_buffer), - "[TRNG] Hardware Entropy: 0x%08lX 0x%08lX 0x%08lX 0x%08lX\r\n\r\nmimxrt1064> ", - (unsigned long)r1, (unsigned long)r2, (unsigned long)r3, (unsigned long)r4); - printf(TAG_TRNG " Generated entropy: 0x%08lX 0x%08lX 0x%08lX 0x%08lX\r\n", - (unsigned long)r1, (unsigned long)r2, (unsigned long)r3, (unsigned long)r4); - send_tcp_response(&shell_socket, resp_buffer); + if (s1 != 0 || s2 != 0 || s3 != 0 || s4 != 0) + { + snprintf(resp_buffer, sizeof(resp_buffer), + "[TRNG] Error: Entropy generation failed (status: %d, %d, %d, %d)\r\n\r\nmimxrt1064> ", + s1, s2, s3, s4); + printf(TAG_TRNG " " MSG_ERROR "Entropy generation failed (status: %d, %d, %d, %d)\r\n", + s1, s2, s3, s4); + send_tcp_response(&shell_socket, resp_buffer); + } + else + { + snprintf(resp_buffer, sizeof(resp_buffer), + "[TRNG] Hardware Entropy: 0x%08lX 0x%08lX 0x%08lX 0x%08lX\r\n\r\nmimxrt1064> ", + (unsigned long)r1, (unsigned long)r2, (unsigned long)r3, (unsigned long)r4); + printf(TAG_TRNG " Generated entropy: 0x%08lX 0x%08lX 0x%08lX 0x%08lX\r\n", + (unsigned long)r1, (unsigned long)r2, (unsigned long)r3, (unsigned long)r4); + send_tcp_response(&shell_socket, resp_buffer); + } } else if (strcmp(line_buffer, "info") == 0) { @@ -313,17 +350,17 @@ static void shell_thread_entry(ULONG thread_input) { if (strstr(line_buffer, "on")) { - USER_LED_ON(); + bsp_led_on(); send_tcp_response(&shell_socket, "[LED] State: ON\r\n\r\nmimxrt1064> "); } else if (strstr(line_buffer, "off")) { - USER_LED_OFF(); + bsp_led_off(); send_tcp_response(&shell_socket, "[LED] State: OFF\r\n\r\nmimxrt1064> "); } else { - USER_LED_TOGGLE(); + bsp_led_toggle(); send_tcp_response(&shell_socket, "[LED] State: TOGGLED\r\n\r\nmimxrt1064> "); } } diff --git a/NXP/MIMXRT1064-EVK/app/demos/threadx_basic/CMakeLists.txt b/targets/NXP/MIMXRT1064-EVK/app/demos/threadx_basic/CMakeLists.txt similarity index 61% rename from NXP/MIMXRT1064-EVK/app/demos/threadx_basic/CMakeLists.txt rename to targets/NXP/MIMXRT1064-EVK/app/demos/threadx_basic/CMakeLists.txt index b8431811..a7ba6275 100644 --- a/NXP/MIMXRT1064-EVK/app/demos/threadx_basic/CMakeLists.txt +++ b/targets/NXP/MIMXRT1064-EVK/app/demos/threadx_basic/CMakeLists.txt @@ -15,31 +15,10 @@ add_executable(${DEMO_TARGET} ) set_target_properties(${DEMO_TARGET} PROPERTIES OUTPUT_NAME "mimxrt1064_threadx") -# Set compile definitions for our executable -target_compile_definitions(${DEMO_TARGET} - PRIVATE - 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 -) - # Include paths for the executable target target_include_directories(${DEMO_TARGET} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} - ${CMAKE_CURRENT_SOURCE_DIR}/../.. - ${SDK_DIR}/CMSIS/Include - ${SDK_DIR}/devices/MIMXRT1064 - ${SDK_DIR}/drivers - ${SDK_DIR}/board - ${SDK_DIR}/utilities - ${SDK_DIR}/components/uart - ${TX_USER_FILE_DIR} ) # Link libraries diff --git a/NXP/MIMXRT1064-EVK/app/demos/threadx_basic/main.c b/targets/NXP/MIMXRT1064-EVK/app/demos/threadx_basic/main.c similarity index 90% rename from NXP/MIMXRT1064-EVK/app/demos/threadx_basic/main.c rename to targets/NXP/MIMXRT1064-EVK/app/demos/threadx_basic/main.c index 6ff1132d..bf868eb8 100644 --- a/NXP/MIMXRT1064-EVK/app/demos/threadx_basic/main.c +++ b/targets/NXP/MIMXRT1064-EVK/app/demos/threadx_basic/main.c @@ -11,19 +11,23 @@ * Ali Eissa - 2026 version. */ -#include "board_init.h" -#include "console.h" -#include "tx_api.h" +#include +#include #include +#include "bsp/board.h" +#include "bsp/led.h" +#include "bsp/console.h" +#include "board_config.h" +#include "tx_api.h" -#define HEARTBEAT_THREAD_STACK_SIZE 1024 -#define WORKER_THREAD_STACK_SIZE 1024 +#define HEARTBEAT_THREAD_STACK_SIZE 2048 +#define WORKER_THREAD_STACK_SIZE 2048 static TX_THREAD heartbeat_thread; -static uint8_t heartbeat_thread_stack[HEARTBEAT_THREAD_STACK_SIZE]; +static ULONG heartbeat_thread_stack[HEARTBEAT_THREAD_STACK_SIZE / sizeof(ULONG)]; static TX_THREAD worker_thread; -static uint8_t worker_thread_stack[WORKER_THREAD_STACK_SIZE]; +static ULONG worker_thread_stack[WORKER_THREAD_STACK_SIZE / sizeof(ULONG)]; static TX_TIMER app_timer; static volatile ULONG timer_fire_count = 0; @@ -35,8 +39,8 @@ static void app_timer_callback(ULONG timer_input); int main(void) { - /* Initialize hardware: MPU, clocks (600 MHz), pins, and LPUART1 */ - board_init(); + /* Initialize hardware via BSP interface */ + bsp_board_init(); printf("\r\n"); printf("==================================================\r\n"); @@ -123,7 +127,7 @@ static void heartbeat_thread_entry(ULONG thread_input) count++; /* Toggle User LED (D18) on GPIO1 Pin 9 */ - USER_LED_TOGGLE(); + bsp_led_toggle(); led_state = !led_state; printf("[Heartbeat Thread] Heartbeat #%lu (System Tick: %lu | User LED: %s)\r\n", diff --git a/NXP/MIMXRT1064-EVK/app/startup/MIMXRT1064xxxxx_flexspi_nor.ld b/targets/NXP/MIMXRT1064-EVK/app/startup/MIMXRT1064xxxxx_flexspi_nor.ld similarity index 100% rename from NXP/MIMXRT1064-EVK/app/startup/MIMXRT1064xxxxx_flexspi_nor.ld rename to targets/NXP/MIMXRT1064-EVK/app/startup/MIMXRT1064xxxxx_flexspi_nor.ld diff --git a/NXP/MIMXRT1064-EVK/app/startup/startup_mimxrt1064.S b/targets/NXP/MIMXRT1064-EVK/app/startup/startup_mimxrt1064.S similarity index 100% rename from NXP/MIMXRT1064-EVK/app/startup/startup_mimxrt1064.S rename to targets/NXP/MIMXRT1064-EVK/app/startup/startup_mimxrt1064.S diff --git a/NXP/MIMXRT1064-EVK/app/startup/tx_initialize_low_level.S b/targets/NXP/MIMXRT1064-EVK/app/startup/tx_initialize_low_level.S similarity index 100% rename from NXP/MIMXRT1064-EVK/app/startup/tx_initialize_low_level.S rename to targets/NXP/MIMXRT1064-EVK/app/startup/tx_initialize_low_level.S diff --git a/NXP/MIMXRT1064-EVK/app/syscalls.c b/targets/NXP/MIMXRT1064-EVK/app/syscalls.c similarity index 100% rename from NXP/MIMXRT1064-EVK/app/syscalls.c rename to targets/NXP/MIMXRT1064-EVK/app/syscalls.c diff --git a/targets/NXP/MIMXRT1064-EVK/app/sysmem.c b/targets/NXP/MIMXRT1064-EVK/app/sysmem.c new file mode 100644 index 00000000..1b10a489 --- /dev/null +++ b/targets/NXP/MIMXRT1064-EVK/app/sysmem.c @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2026 Eclipse ThreadX contributors + * + * 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. + */ + +#include "tx_api.h" +#include +#include +#include +#include + +/** + * Pointer to the current high watermark of the heap usage + */ +static uint8_t *__sbrk_heap_end = NULL; + +/** + * Depth and interrupt posture for re-entrant newlib malloc locking + */ +static unsigned int s_malloc_lock_posture = 0; +static uint32_t s_malloc_lock_depth = 0; + +void __malloc_lock(struct _reent *reent) +{ + (void)reent; + TX_INTERRUPT_SAVE_AREA + TX_DISABLE + if (s_malloc_lock_depth == 0U) + { + s_malloc_lock_posture = interrupt_save; + } + s_malloc_lock_depth++; +} + +void __malloc_unlock(struct _reent *reent) +{ + (void)reent; + if (s_malloc_lock_depth == 0U) + { + return; + } + s_malloc_lock_depth--; + if (s_malloc_lock_depth == 0U) + { + TX_INTERRUPT_SAVE_AREA + interrupt_save = s_malloc_lock_posture; + TX_RESTORE + } +} + +/** + * @brief _sbrk() allocates memory to the newlib heap and is used by malloc. + */ +void *_sbrk(ptrdiff_t incr) +{ + extern uint8_t _end; + extern uint8_t __heap_limit; + const uint8_t *max_heap = &__heap_limit; + uint8_t *prev_heap_end; + + TX_INTERRUPT_SAVE_AREA + TX_DISABLE + + /* Initialize heap end at first call */ + if (NULL == __sbrk_heap_end) + { + __sbrk_heap_end = &_end; + } + + /* Protect heap from growing beyond linker-defined heap limit without overflow */ + if (incr > 0) + { + if ((uintptr_t)incr > (uintptr_t)(max_heap - __sbrk_heap_end)) + { + TX_RESTORE + errno = ENOMEM; + return (void *)-1; + } + } + else if (incr < 0) + { + uintptr_t dec = (uintptr_t)(-incr); + if (dec > (uintptr_t)(__sbrk_heap_end - &_end)) + { + TX_RESTORE + errno = EINVAL; + return (void *)-1; + } + } + + prev_heap_end = __sbrk_heap_end; + __sbrk_heap_end += incr; + + TX_RESTORE + return (void *)prev_heap_end; +} diff --git a/targets/NXP/MIMXRT1064-EVK/app/trng.c b/targets/NXP/MIMXRT1064-EVK/app/trng.c new file mode 100644 index 00000000..428be528 --- /dev/null +++ b/targets/NXP/MIMXRT1064-EVK/app/trng.c @@ -0,0 +1,197 @@ +/* + * Copyright (c) 2026 Eclipse ThreadX contributors + * + * 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. + */ + +#include "trng.h" +#include "fsl_device_registers.h" +#include "fsl_clock.h" +#include "tx_api.h" +#include + +#define TRNG_TIMEOUT_CYCLES 1000000UL +#define TRNG_ENTROPY_WORDS 16 + +/* Recommended sampling and delay parameters according to NXP Reference Manual */ +#define TRNG_SAMPLE_SIZE_DEF 2500U +#define TRNG_ENTROPY_DLY_DEF 3200U + +/* + * Static entropy pool buffer caching a full 512-bit hardware entropy block + * (16 words * 32 bits = 512 bits) read from ENT[0..15]. + */ +static uint32_t s_entropy_pool[TRNG_ENTROPY_WORDS]; +static size_t s_pool_index = TRNG_ENTROPY_WORDS; /* Initially empty */ + +/* ThreadX mutex for mutual exclusion across concurrent threads */ +static TX_MUTEX s_trng_mutex; +static bool s_trng_mutex_created = false; + +/* Helper to acquire mutex if ThreadX kernel is running */ +static inline void trng_mutex_lock(void) +{ + if (s_trng_mutex_created && (tx_thread_identify() != TX_NULL)) + { + tx_mutex_get(&s_trng_mutex, TX_WAIT_FOREVER); + } +} + +/* Helper to release mutex if ThreadX kernel is running */ +static inline void trng_mutex_unlock(void) +{ + if (s_trng_mutex_created && (tx_thread_identify() != TX_NULL)) + { + tx_mutex_put(&s_trng_mutex); + } +} + +int trng_init(void) +{ + /* Initialize ThreadX mutex once for thread-safe access */ + if (!s_trng_mutex_created) + { + if (tx_mutex_create(&s_trng_mutex, "TRNG Mutex", TX_INHERIT) == TX_SUCCESS) + { + s_trng_mutex_created = true; + } + } + + trng_mutex_lock(); + + /* 1. Enable TRNG peripheral clock in CCM */ + CLOCK_EnableClock(kCLOCK_Trng); + + /* 2. Enter Program Mode to allow programming control & delay registers */ + TRNG->MCTL |= TRNG_MCTL_PRGM_MASK; + + /* 3. Reset TRNG registers to hardware defaults (and clear ERR flag) */ + TRNG->MCTL |= TRNG_MCTL_RST_DEF_MASK; + + /* 4. Configure entropy sample size and delay parameters in SDCTL */ + TRNG->SDCTL = TRNG_SDCTL_ENT_DLY(TRNG_ENTROPY_DLY_DEF) | + TRNG_SDCTL_SAMP_SIZE(TRNG_SAMPLE_SIZE_DEF); + + /* 5. Set Von Neumann sampling mode (0b00) and un-divided oscillator (0b00) */ + TRNG->MCTL = (TRNG->MCTL & ~(TRNG_MCTL_SAMP_MODE_MASK | TRNG_MCTL_OSC_DIV_MASK)) | + TRNG_MCTL_SAMP_MODE(0) | TRNG_MCTL_OSC_DIV(0); + + /* 6. Exit Program Mode to enter Run Mode. + * In NXP hardware, transitioning PRGM from 1 to 0 actively initiates + * the entropy generation state machine. + */ + TRNG->MCTL &= ~TRNG_MCTL_PRGM_MASK; + + /* Invalidate local entropy pool */ + s_pool_index = TRNG_ENTROPY_WORDS; + + trng_mutex_unlock(); + + return 0; +} + +int trng_get_random_u32(uint32_t *random_val) +{ + uint32_t timeout; + + if (random_val == NULL) + { + return -1; + } + + /* + * Mutex serializes access among concurrent threads (e.g. multiple shell sessions), + * preventing race conditions on observing ENT_VAL and reading ENT registers. + */ + trng_mutex_lock(); + + /* If cached entropy is available, dispense immediately without hardware wait */ + if (s_pool_index < TRNG_ENTROPY_WORDS) + { + *random_val = s_entropy_pool[s_pool_index++]; + trng_mutex_unlock(); + return 0; + } + + /* If hardware reports an error, recover via documented re-initialization */ + if (TRNG->MCTL & TRNG_MCTL_ERR_MASK) + { + trng_init(); + } + + /* Wait for Entropy Valid (ENT_VAL) bit */ + timeout = TRNG_TIMEOUT_CYCLES; + while (!(TRNG->MCTL & TRNG_MCTL_ENT_VAL_MASK)) + { + if (--timeout == 0) + { + trng_mutex_unlock(); + return -2; /* Timeout waiting for entropy */ + } + } + + /* + * Read all 16 entropy registers (ENT[0] through ENT[15]). + * + * Per the NXP i.MX RT1060 Reference Manual (TRNG section): + * Reading ENT15 is the hardware signal that acknowledges and consumes the + * 512-bit entropy block, automatically clears MCTL[ENT_VAL] to 0, and + * initiates the next hardware entropy generation cycle. + */ + for (size_t i = 0; i < TRNG_ENTROPY_WORDS; i++) + { + s_entropy_pool[i] = TRNG->ENT[i]; + } + s_pool_index = 0; + + *random_val = s_entropy_pool[s_pool_index++]; + + trng_mutex_unlock(); + return 0; +} + +int trng_get_random_data(void *buffer, size_t length) +{ + uint8_t *out = (uint8_t *)buffer; + size_t offset = 0; + uint32_t rand_word; + int status; + + if (buffer == NULL) + { + return -1; + } + + /* Acquire mutex to ensure the buffer is filled contiguously without thread interleaving */ + trng_mutex_lock(); + + while (offset < length) + { + status = trng_get_random_u32(&rand_word); + if (status != 0) + { + trng_mutex_unlock(); + return status; + } + + size_t chunk = length - offset; + if (chunk > sizeof(uint32_t)) + { + chunk = sizeof(uint32_t); + } + + memcpy(out + offset, &rand_word, chunk); + offset += chunk; + } + + trng_mutex_unlock(); + + return (int)length; +} diff --git a/NXP/MIMXRT1064-EVK/app/trng.h b/targets/NXP/MIMXRT1064-EVK/app/trng.h similarity index 100% rename from NXP/MIMXRT1064-EVK/app/trng.h rename to targets/NXP/MIMXRT1064-EVK/app/trng.h diff --git a/NXP/MIMXRT1064-EVK/cmake/arm-gcc-cortex-m7.cmake b/targets/NXP/MIMXRT1064-EVK/cmake/arm-gcc-cortex-m7.cmake similarity index 100% rename from NXP/MIMXRT1064-EVK/cmake/arm-gcc-cortex-m7.cmake rename to targets/NXP/MIMXRT1064-EVK/cmake/arm-gcc-cortex-m7.cmake diff --git a/NXP/MIMXRT1064-EVK/cmake/arm-gcc-cortex-toolchain.cmake b/targets/NXP/MIMXRT1064-EVK/cmake/arm-gcc-cortex-toolchain.cmake similarity index 100% rename from NXP/MIMXRT1064-EVK/cmake/arm-gcc-cortex-toolchain.cmake rename to targets/NXP/MIMXRT1064-EVK/cmake/arm-gcc-cortex-toolchain.cmake diff --git a/NXP/MIMXRT1064-EVK/cmake/utilities.cmake b/targets/NXP/MIMXRT1064-EVK/cmake/utilities.cmake similarity index 100% rename from NXP/MIMXRT1064-EVK/cmake/utilities.cmake rename to targets/NXP/MIMXRT1064-EVK/cmake/utilities.cmake diff --git a/targets/NXP/MIMXRT1064-EVK/lib/bsp/CMakeLists.txt b/targets/NXP/MIMXRT1064-EVK/lib/bsp/CMakeLists.txt new file mode 100644 index 00000000..a25f1a88 --- /dev/null +++ b/targets/NXP/MIMXRT1064-EVK/lib/bsp/CMakeLists.txt @@ -0,0 +1,52 @@ +# Copyright (c) 2026 Eclipse ThreadX contributors +# +# This program and the accompanying materials are made available +# under the terms of the MIT license which is available at +# https://opensource.org/licenses/MIT. +# +# SPDX-License-Identifier: MIT + +# Board Support Package implementation for NXP MIMXRT1064-EVK +add_library(mimxrt1064_bsp STATIC + src/bsp_board.c + src/bsp_led.c + src/bsp_console.c + src/bsp_memory.c + src/bsp_selftest.c +) + +target_include_directories(mimxrt1064_bsp + PUBLIC + include + ${SHARED_BSP_DIR}/include +) + +target_link_libraries(mimxrt1064_bsp + PUBLIC + mimxrt1064_common + ${SDK_TARGET} + threadx +) + +# Board startup, low-level ThreadX initialization, syscalls, and hardware TRNG +add_library(board_bsp OBJECT + ${CMAKE_CURRENT_SOURCE_DIR}/../../app/startup/startup_mimxrt1064.S + ${CMAKE_CURRENT_SOURCE_DIR}/../../app/startup/tx_initialize_low_level.S + ${CMAKE_CURRENT_SOURCE_DIR}/../../app/sysmem.c + ${CMAKE_CURRENT_SOURCE_DIR}/../../app/syscalls.c + ${CMAKE_CURRENT_SOURCE_DIR}/../../app/trng.c +) + +target_include_directories(board_bsp + PUBLIC + include + ${SHARED_BSP_DIR}/include +) + +target_link_libraries(board_bsp + PUBLIC + mimxrt1064_common + mimxrt1064_bsp + ${SDK_TARGET} + threadx +) diff --git a/targets/NXP/MIMXRT1064-EVK/lib/bsp/include/board_config.h b/targets/NXP/MIMXRT1064-EVK/lib/bsp/include/board_config.h new file mode 100644 index 00000000..237bb395 --- /dev/null +++ b/targets/NXP/MIMXRT1064-EVK/lib/bsp/include/board_config.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2026 Eclipse ThreadX contributors + * + * This program and the accompanying materials are made available + * under the terms of the MIT license which is available at + * https://opensource.org/licenses/MIT. + * + * SPDX-License-Identifier: MIT + */ + +#ifndef BOARD_CONFIG_H +#define BOARD_CONFIG_H + +#include +#include + +#define BSP_BOARD_NAME "MIMXRT1064-EVK" +#define BSP_CORE_CLOCK_HZ 600000000UL +#define BSP_CPU_CLOCK_HZ BSP_CORE_CLOCK_HZ +#define BSP_SYSTEM_CLOCK_HZ BSP_CORE_CLOCK_HZ +#define BSP_UART_BAUDRATE 115200U + +#define BSP_HAS_LED 1 +#define BSP_HAS_CONSOLE 1 + +/* Memory configuration (DTCM data RAM) */ +#define BSP_RAM_START 0x20000000UL +#define BSP_RAM_SIZE 0x00020000UL /* 128 KB DTCM */ +#define BSP_RAM_END (BSP_RAM_START + BSP_RAM_SIZE) +#define BSP_MAIN_STACK_RESERVE 0x00000400UL /* 1 KB main stack */ + +extern uint32_t SystemCoreClock; + +#endif /* BOARD_CONFIG_H */ diff --git a/NXP/MIMXRT1064-EVK/app/board_init.c b/targets/NXP/MIMXRT1064-EVK/lib/bsp/src/bsp_board.c similarity index 57% rename from NXP/MIMXRT1064-EVK/app/board_init.c rename to targets/NXP/MIMXRT1064-EVK/lib/bsp/src/bsp_board.c index 0517fb0b..2dc26966 100644 --- a/NXP/MIMXRT1064-EVK/app/board_init.c +++ b/targets/NXP/MIMXRT1064-EVK/lib/bsp/src/bsp_board.c @@ -1,24 +1,27 @@ /* * Copyright (c) 2026 Eclipse ThreadX contributors * - * This program and the accompanying materials are made available + * 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. + * https://opensource.org/licenses/MIT. * * SPDX-License-Identifier: MIT - * - * Contributors: - * Ali Eissa - 2026 version. */ -#include "board_init.h" -#include "console.h" +#include "bsp/board.h" +#include "bsp/led.h" +#include "bsp/console.h" +#include "board_config.h" + +#include "board.h" +#include "pin_mux.h" +#include "clock_config.h" #include "fsl_iomuxc.h" #include "fsl_gpio.h" -void board_init(void) +void bsp_board_init(void) { - /* 1. Configure the Memory Protection Unit if supported by hardware (16 regions on real Cortex-M7 silicon) */ + /* 1. Configure the Memory Protection Unit if supported by hardware */ if (((MPU->TYPE & MPU_TYPE_DREGION_Msk) >> MPU_TYPE_DREGION_Pos) >= 12) { BOARD_ConfigMPU(); @@ -35,18 +38,10 @@ void board_init(void) /* 4. Configure System Clocks (600 MHz AHB core clock) */ BOARD_BootClockRUN(); - /* 5. Initialize User LED GPIO (GPIO1 Pin 9, output, initial state OFF) */ - gpio_pin_config_t led_config = { - kGPIO_DigitalOutput, - 0, - kGPIO_NoIntmode - }; - GPIO_PinInit(BOARD_USER_LED_GPIO, BOARD_USER_LED_GPIO_PIN, &led_config); - USER_LED_OFF(); - - /* 6. Initialize LPUART1 Serial Console at 115200 baud */ - console_init(); + /* 5. Initialize User LED and Console via standard BSP interfaces */ + bsp_led_init(); + bsp_console_init(); - /* 7. Configure Ethernet Pin Muxing (RMII and MDC/MDIO) */ + /* 6. Configure Ethernet Pin Muxing (RMII and MDC/MDIO) */ BOARD_InitENET(); } diff --git a/targets/NXP/MIMXRT1064-EVK/lib/bsp/src/bsp_console.c b/targets/NXP/MIMXRT1064-EVK/lib/bsp/src/bsp_console.c new file mode 100644 index 00000000..d5c7a54c --- /dev/null +++ b/targets/NXP/MIMXRT1064-EVK/lib/bsp/src/bsp_console.c @@ -0,0 +1,162 @@ +/* + * Copyright (c) 2026 Eclipse ThreadX contributors + * + * This program and the accompanying materials are made available + * under the terms of the MIT license which is available at + * https://opensource.org/licenses/MIT. + * + * SPDX-License-Identifier: MIT + */ + +#include "bsp/console.h" +#include "board_config.h" + +#include "fsl_lpuart.h" +#include "board.h" +#include "tx_api.h" + +#include +#include +#include + +#if BSP_HAS_CONSOLE +static bsp_console_rx_fn volatile console_rx_handler = NULL; +static void *volatile console_rx_context = NULL; +static TX_MUTEX s_console_mutex; +static volatile int s_console_mutex_created = 0; + +static void console_putc(char c) +{ + if (c == '\n') + { + while (!(LPUART_GetStatusFlags(LPUART1) & (uint32_t)kLPUART_TxDataRegEmptyFlag)) + { + } + LPUART_WriteByte(LPUART1, (uint8_t)'\r'); + } + + while (!(LPUART_GetStatusFlags(LPUART1) & (uint32_t)kLPUART_TxDataRegEmptyFlag)) + { + } + LPUART_WriteByte(LPUART1, (uint8_t)c); +} +#endif + +void bsp_console_init(void) +{ +#if BSP_HAS_CONSOLE + lpuart_config_t config; + + LPUART_GetDefaultConfig(&config); + config.baudRate_Bps = BSP_UART_BAUDRATE; + config.enableTx = true; + config.enableRx = true; + + uint32_t uartClkSrcFreq = BOARD_DebugConsoleSrcFreq(); + LPUART_Init(LPUART1, &config, uartClkSrcFreq); + + /* Set stdout and stderr to unbuffered mode so newlib printf never + * allocates dynamic heap buffers during multi-threaded execution. */ + setvbuf(stdout, NULL, _IONBF, 0); + setvbuf(stderr, NULL, _IONBF, 0); +#endif +} + +void bsp_console_write(const char *data, size_t length) +{ +#if BSP_HAS_CONSOLE + if ((data == NULL) || (length == 0U)) + { + return; + } + + int locked = 0; + /* Only acquire mutex if ThreadX is running, in thread mode, and not inside an ISR */ + if ((__get_IPSR() == 0U) && (tx_thread_identify() != TX_NULL)) + { + if (!s_console_mutex_created) + { + TX_INTERRUPT_SAVE_AREA + TX_DISABLE + if (!s_console_mutex_created) + { + if (tx_mutex_create(&s_console_mutex, "Console Mutex", TX_NO_INHERIT) == TX_SUCCESS) + { + s_console_mutex_created = 1; + } + } + TX_RESTORE + } + + if (s_console_mutex_created) + { + if (tx_mutex_get(&s_console_mutex, TX_WAIT_FOREVER) == TX_SUCCESS) + { + locked = 1; + } + } + } + + for (size_t i = 0U; i < length; i++) + { + console_putc(data[i]); + } + + if (locked) + { + tx_mutex_put(&s_console_mutex); + } +#else + (void)data; + (void)length; +#endif +} + +void bsp_console_set_rx_handler(bsp_console_rx_fn handler, void *context) +{ +#if BSP_HAS_CONSOLE + console_rx_context = context; + console_rx_handler = handler; +#else + (void)handler; + (void)context; +#endif +} + +/* Backward compatibility wrapper for existing code calling console_write */ +void console_write(const char *str) +{ + if (str != NULL) + { + size_t len = 0; + while (str[len] != '\0') + { + len++; + } + bsp_console_write(str, len); + } +} + +/* C runtime newlib redirection */ +int _write(int file, char *ptr, int len) +{ + (void)file; + if (len > 0 && ptr != NULL) + { + bsp_console_write(ptr, (size_t)len); + } + return len; +} + +int _read(int file, char *ptr, int len) +{ + (void)file; + for (int i = 0; i < len; i++) + { + while (!(LPUART_GetStatusFlags(LPUART1) & (uint32_t)kLPUART_RxDataRegFullFlag)) + { + } + ptr[i] = (char)LPUART_ReadByte(LPUART1); + } + return len; +} diff --git a/targets/NXP/MIMXRT1064-EVK/lib/bsp/src/bsp_led.c b/targets/NXP/MIMXRT1064-EVK/lib/bsp/src/bsp_led.c new file mode 100644 index 00000000..3b2ae78f --- /dev/null +++ b/targets/NXP/MIMXRT1064-EVK/lib/bsp/src/bsp_led.c @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2026 Eclipse ThreadX contributors + * + * This program and the accompanying materials are made available + * under the terms of the MIT license which is available at + * https://opensource.org/licenses/MIT. + * + * SPDX-License-Identifier: MIT + */ + +#include "bsp/led.h" +#include "board_config.h" + +#include "board.h" +#include "fsl_gpio.h" + +void bsp_led_init(void) +{ +#if BSP_HAS_LED + gpio_pin_config_t led_config = { + kGPIO_DigitalOutput, + 1, /* Initial output HIGH (active-low LED D18 is OFF) */ + kGPIO_NoIntmode + }; + GPIO_PinInit(BOARD_USER_LED_GPIO, BOARD_USER_LED_GPIO_PIN, &led_config); + bsp_led_off(); +#endif +} + +void bsp_led_on(void) +{ +#if BSP_HAS_LED + /* Active-low: logic 0 turns the LED ON */ + GPIO_PinWrite(BOARD_USER_LED_GPIO, BOARD_USER_LED_GPIO_PIN, 0U); +#endif +} + +void bsp_led_off(void) +{ +#if BSP_HAS_LED + /* Active-low: logic 1 turns the LED OFF */ + GPIO_PinWrite(BOARD_USER_LED_GPIO, BOARD_USER_LED_GPIO_PIN, 1U); +#endif +} + +void bsp_led_toggle(void) +{ +#if BSP_HAS_LED + uint32_t current = GPIO_PinRead(BOARD_USER_LED_GPIO, BOARD_USER_LED_GPIO_PIN); + GPIO_PinWrite(BOARD_USER_LED_GPIO, BOARD_USER_LED_GPIO_PIN, (uint8_t)(current ^ 1U)); +#endif +} diff --git a/targets/NXP/MIMXRT1064-EVK/lib/bsp/src/bsp_memory.c b/targets/NXP/MIMXRT1064-EVK/lib/bsp/src/bsp_memory.c new file mode 100644 index 00000000..7f834ba4 --- /dev/null +++ b/targets/NXP/MIMXRT1064-EVK/lib/bsp/src/bsp_memory.c @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2026 Eclipse ThreadX contributors + * + * This program and the accompanying materials are made available + * under the terms of the MIT license which is available at + * https://opensource.org/licenses/MIT. + * + * SPDX-License-Identifier: MIT + */ + +#include "bsp/memory.h" +#include "board_config.h" +#include +#include + +void bsp_ram_region(void *first_unused, void **base, size_t *size) +{ + const uintptr_t start = (uintptr_t)first_unused; + const uintptr_t end = (uintptr_t)BSP_RAM_END - (uintptr_t)BSP_MAIN_STACK_RESERVE; + + *base = first_unused; + *size = (end > start) ? (size_t)(end - start) : (size_t)0U; +} diff --git a/targets/NXP/MIMXRT1064-EVK/lib/bsp/src/bsp_selftest.c b/targets/NXP/MIMXRT1064-EVK/lib/bsp/src/bsp_selftest.c new file mode 100644 index 00000000..df164a08 --- /dev/null +++ b/targets/NXP/MIMXRT1064-EVK/lib/bsp/src/bsp_selftest.c @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2026 Eclipse ThreadX contributors + * + * This program and the accompanying materials are made available + * under the terms of the MIT license which is available at + * https://opensource.org/licenses/MIT. + * + * SPDX-License-Identifier: MIT + */ + +#include "bsp/selftest.h" +#include "board_config.h" +#include "fsl_common.h" +#include + +typedef struct { + bsp_selftest_report_fn report; + void *context; + unsigned failures; +} selftest_state_t; + +static void check(selftest_state_t *state, int passed, const char *message) +{ + if (passed == 0) + { + state->failures++; + } + state->report(passed, message, state->context); +} + +unsigned bsp_self_test(bsp_selftest_report_fn report, void *context) +{ + selftest_state_t state; + + if (report == NULL) + { + return 1U; + } + + state.report = report; + state.context = context; + state.failures = 0U; + + /* 1. System core clock sanity check */ + check(&state, (SystemCoreClock >= 10000000UL), "Core clock initialized"); + + /* 2. Board name verified */ + check(&state, (sizeof(BSP_BOARD_NAME) > 1), "Board identification valid"); + + return state.failures; +} diff --git a/targets/NXP/MIMXRT1064-EVK/lib/netx_driver/gnu/nx_driver_imxrt1062_low_level.S b/targets/NXP/MIMXRT1064-EVK/lib/netx_driver/gnu/nx_driver_imxrt1062_low_level.S new file mode 100644 index 00000000..88b35178 --- /dev/null +++ b/targets/NXP/MIMXRT1064-EVK/lib/netx_driver/gnu/nx_driver_imxrt1062_low_level.S @@ -0,0 +1,84 @@ +@/**************************************************************************/ +@/* */ +@/* Copyright (c) Microsoft Corporation. All rights reserved. */ +@/* */ +@/* This software is licensed under the Microsoft Software License */ +@/* Terms for Microsoft Azure RTOS. Full text of the license can be */ +@/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */ +@/* and in the root directory of this software. */ +@/* */ +@/**************************************************************************/ +@ +@ +@/**************************************************************************/ +@/**************************************************************************/ +@/** */ +@/** ThreadX Component */ +@/** */ +@/** Initialize */ +@/** */ +@/**************************************************************************/ +@/**************************************************************************/ +@ +@#define TX_SOURCE_CODE +@ +@ + .global nx_driver_imx_ethernet_isr + + .text 32 + .align 4 + .syntax unified +@/**************************************************************************/ +@/* */ +@/* FUNCTION RELEASE */ +@/* */ +@/* ENET_Transmit_IRQHandler MIMXRT1060/GCC */ +@/* 5.0 */ +@/* AUTHOR */ +@/* */ +@/* William E. Lamie, Microsoft Corporation */ +@/* */ +@/* DESCRIPTION */ +@/* */ +@/* This function is responsible for fielding the ethernet interrupts */ +@/* of the MIMXRT1060. */ +@/* */ +@/* INPUT */ +@/* */ +@/* None */ +@/* */ +@/* OUTPUT */ +@/* */ +@/* None */ +@/* */ +@/* CALLS */ +@/* */ +@/* nx_driver_imx_ethernet_isr NetX driver ethernet ISR */ +@/* */ +@/* CALLED BY */ +@/* */ +@/* _tx_initialize_kernel_enter ThreadX entry function */ +@/* */ +@/* RELEASE HISTORY */ +@/* */ +@/* DATE NAME DESCRIPTION */ +@/* */ +@/* 02-01-2018 William E. Lamie Initial Version 5.0 */ +@/* */ +@/**************************************************************************/ + .global __nx_ENET_IRQHandler + .global ENET_IRQHandler + .thumb_func +__nx_ENET_IRQHandler: + .thumb_func +ENET_IRQHandler: + PUSH {r0, lr} +#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY + BL _tx_execution_isr_enter @ Call the ISR enter function +#endif + BL nx_driver_imx_ethernet_isr +#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY + BL _tx_execution_isr_exit @ Call the ISR exit function +#endif + POP {r0, lr} + BX lr diff --git a/targets/NXP/MIMXRT1064-EVK/lib/netx_driver/nx_driver_imxrt1062.c b/targets/NXP/MIMXRT1064-EVK/lib/netx_driver/nx_driver_imxrt1062.c new file mode 100644 index 00000000..1f99cc25 --- /dev/null +++ b/targets/NXP/MIMXRT1064-EVK/lib/netx_driver/nx_driver_imxrt1062.c @@ -0,0 +1,2870 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) Microsoft Corporation. All rights reserved. */ +/* */ +/* This software is licensed under the Microsoft Software License */ +/* Terms for Microsoft Azure RTOS. Full text of the license can be */ +/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */ +/* and in the root directory of this software. */ +/* */ +/**************************************************************************/ + + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** NetX Component */ +/** */ +/** Ethernet device driver for IMX family micro processors */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +/* Indicate that driver source is being compiled. */ + +#define NX_DRIVER_SOURCE + + +/****** DRIVER SPECIFIC ****** Start of part/vendor specific include area. Include driver-specific include file here! */ + +#ifndef NX_DRIVER_IMXRT1062_H + +/* Determine if the driver uses IP deferred processing or direct ISR processing. */ + +#define NX_DRIVER_ENABLE_DEFERRED /* Define this to enable deferred ISR processing. */ + +/* #define ENET_ENHANCEDBUFFERDESCRIPTOR_MODE*/ +/* Determine if the packet transmit queue logic is required for this driver. */ + +/* No, not required for this driver. #define NX_DIRVER_INTERNAL_TRANSMIT_QUEUE */ + +/* Include driver specific include file. */ +#include "nx_driver_imxrt1062.h" + +#endif + +/****** DRIVER SPECIFIC ****** End of part/vendor specific include file area! */ + + +/* Define the driver information structure that is only available within this file. */ + +static NX_DRIVER_INFORMATION nx_driver_information; + + +/****** DRIVER SPECIFIC ****** Start of part/vendor specific data area. Include hardware-specific data here! */ + +/* Define driver specific ethernet hardware address. */ + +#ifndef NX_DRIVER_ETHERNET_MAC +UCHAR _nx_driver_hardware_address[] = {0x02, 0x11, 0x22, 0x33, 0x44, 0x52}; +#else +UCHAR _nx_driver_hardware_address[] = NX_DRIVER_ETHERNET_MAC; +#endif + + +/****** DRIVER SPECIFIC ****** End of part/vendor specific data area! */ + + +/* Define the routines for processing each driver entry request. The contents of these routines will change with + each driver. However, the main driver entry function will not change, except for the entry function name. */ + +static VOID _nx_driver_interface_attach(NX_IP_DRIVER *driver_req_ptr); +static VOID _nx_driver_initialize(NX_IP_DRIVER *driver_req_ptr); +static VOID _nx_driver_enable(NX_IP_DRIVER *driver_req_ptr); +static VOID _nx_driver_disable(NX_IP_DRIVER *driver_req_ptr); +static VOID _nx_driver_packet_send(NX_IP_DRIVER *driver_req_ptr); +static VOID _nx_driver_multicast_join(NX_IP_DRIVER *driver_req_ptr); +static VOID _nx_driver_multicast_leave(NX_IP_DRIVER *driver_req_ptr); +static VOID _nx_driver_get_status(NX_IP_DRIVER *driver_req_ptr); +#ifdef NX_DRIVER_ENABLE_DEFERRED +static VOID _nx_driver_deferred_processing(NX_IP_DRIVER *driver_req_ptr); +#endif +static VOID _nx_driver_transfer_to_netx(NX_IP *ip_ptr, NX_PACKET *packet_ptr); +#ifdef NX_DIRVER_INTERNAL_TRANSMIT_QUEUE +static VOID _nx_driver_transmit_packet_enqueue(NX_PACKET *packet_ptr) +static NX_PACKET *_nx_driver_transmit_packet_dequeue(VOID) +#endif +#ifdef NX_ENABLE_INTERFACE_CAPABILITY +static VOID _nx_driver_capability_get(NX_IP_DRIVER *driver_req_ptr); +static VOID _nx_driver_capability_set(NX_IP_DRIVER *driver_req_ptr); +#endif /* NX_ENABLE_INTERFACE_CAPABILITY */ + +/* Define the prototypes for the hardware implementation of this driver. The contents of these routines are + driver-specific. */ + +static UINT _nx_driver_hardware_initialize(NX_IP_DRIVER *driver_req_ptr); +static UINT _nx_driver_hardware_enable(NX_IP_DRIVER *driver_req_ptr); +static UINT _nx_driver_hardware_disable(NX_IP_DRIVER *driver_req_ptr); +static UINT _nx_driver_hardware_packet_send(NX_PACKET *packet_ptr); +static UINT _nx_driver_hardware_multicast_join(NX_IP_DRIVER *driver_req_ptr); +static UINT _nx_driver_hardware_multicast_leave(NX_IP_DRIVER *driver_req_ptr); +static UINT _nx_driver_hardware_get_status(NX_IP_DRIVER *driver_req_ptr); +static VOID _nx_driver_hardware_packet_transmitted(VOID); +static VOID _nx_driver_hardware_packet_received(VOID); +#ifdef NX_ENABLE_INTERFACE_CAPABILITY +static UINT _nx_driver_hardware_capability_set(NX_IP_DRIVER *driver_req_ptr); +#endif + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* nx_driver_imx PORTABLE C */ +/* 6.1 */ +/* AUTHOR */ +/* */ +/* Yuxin Zhou, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This is the entry point of the NetX Ethernet Driver. This driver */ +/* function is responsible for initializing the Ethernet controller, */ +/* enabling or disabling the controller as need, preparing */ +/* a packet for transmission, and getting status information. */ +/* */ +/* INPUT */ +/* */ +/* driver_req_ptr The driver request from the */ +/* IP layer. */ +/* */ +/* OUTPUT */ +/* */ +/* None */ +/* */ +/* CALLS */ +/* */ +/* _nx_driver_interface_attach Process attach request */ +/* _nx_driver_initialize Process initialize request */ +/* _nx_driver_enable Process link enable request */ +/* _nx_driver_disable Process link disable request */ +/* _nx_driver_packet_send Process send packet requests */ +/* _nx_driver_multicast_join Process multicast join request*/ +/* _nx_driver_multicast_leave Process multicast leave req */ +/* _nx_driver_get_status Process get status request */ +/* _nx_driver_deferred_processing Drive deferred processing */ +/* */ +/* CALLED BY */ +/* */ +/* IP layer */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */ +/* 09-30-2020 Yuxin Zhou Modified comment(s), */ +/* resulting in version 6.1 */ +/* */ +/**************************************************************************/ +/****** DRIVER SPECIFIC ****** Start of part/vendor specific global driver entry function name. */ +VOID nx_driver_imx(NX_IP_DRIVER *driver_req_ptr) +/****** DRIVER SPECIFIC ****** End of part/vendor specific global driver entry function name. */ +{ + + /* Default to successful return. */ + driver_req_ptr -> nx_ip_driver_status = NX_SUCCESS; + + /* Process according to the driver request type in the IP control + block. */ + switch (driver_req_ptr -> nx_ip_driver_command) + { + + case NX_LINK_INTERFACE_ATTACH: + + /* Process link interface attach requests. */ + _nx_driver_interface_attach(driver_req_ptr); + break; + + case NX_LINK_INITIALIZE: + { + + /* Process link initialize requests. */ + _nx_driver_initialize(driver_req_ptr); + break; + } + + case NX_LINK_ENABLE: + { + + /* Process link enable requests. */ + _nx_driver_enable(driver_req_ptr); + break; + } + + case NX_LINK_DISABLE: + { + + /* Process link disable requests. */ + _nx_driver_disable(driver_req_ptr); + break; + } + + + case NX_LINK_ARP_SEND: + case NX_LINK_ARP_RESPONSE_SEND: + case NX_LINK_PACKET_BROADCAST: + case NX_LINK_RARP_SEND: + case NX_LINK_PACKET_SEND: + { + + /* Process packet send requests. */ + _nx_driver_packet_send(driver_req_ptr); + break; + } + + + case NX_LINK_MULTICAST_JOIN: + { + + /* Process multicast join requests. */ + _nx_driver_multicast_join(driver_req_ptr); + break; + } + + + case NX_LINK_MULTICAST_LEAVE: + { + + /* Process multicast leave requests. */ + _nx_driver_multicast_leave(driver_req_ptr); + break; + } + + case NX_LINK_GET_STATUS: + { + + /* Process get status requests. */ + _nx_driver_get_status(driver_req_ptr); + break; + } +#ifdef NX_DRIVER_ENABLE_DEFERRED + case NX_LINK_DEFERRED_PROCESSING: + { + + /* Process driver deferred requests. */ + + /* Process a device driver function on behave of the IP thread. */ + _nx_driver_deferred_processing(driver_req_ptr); + break; + } +#endif +#ifdef NX_ENABLE_INTERFACE_CAPABILITY + case NX_INTERFACE_CAPABILITY_GET: + { + + /* Process get capability requests. */ + _nx_driver_capability_get(driver_req_ptr); + break; + } + + case NX_INTERFACE_CAPABILITY_SET: + { + + /* Process set capability requests. */ + _nx_driver_capability_set(driver_req_ptr); + break; + } +#endif /* NX_ENABLE_INTERFACE_CAPABILITY */ + default: + + /* Invalid driver request. */ + + /* Return the unhandled command status. */ + driver_req_ptr -> nx_ip_driver_status = NX_UNHANDLED_COMMAND; + + /* Default to successful return. */ + driver_req_ptr -> nx_ip_driver_status = NX_DRIVER_ERROR; + } +} + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _nx_driver_interface_attach PORTABLE C */ +/* 6.1 */ +/* AUTHOR */ +/* */ +/* Yuxin Zhou, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function processing the interface attach request. */ +/* */ +/* INPUT */ +/* */ +/* driver_req_ptr Driver command from the IP */ +/* thread */ +/* */ +/* OUTPUT */ +/* */ +/* None */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* CALLED BY */ +/* */ +/* Driver entry function */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */ +/* 09-30-2020 Yuxin Zhou Modified comment(s), */ +/* resulting in version 6.1 */ +/* */ +/**************************************************************************/ +static VOID _nx_driver_interface_attach(NX_IP_DRIVER *driver_req_ptr) +{ + + + /* Setup the driver's interface. This example is for a simple one-interface + Ethernet driver. Additional logic is necessary for multiple port devices. */ + nx_driver_information.nx_driver_information_interface = driver_req_ptr -> nx_ip_driver_interface; + +#ifdef NX_ENABLE_INTERFACE_CAPABILITY + driver_req_ptr -> nx_ip_driver_interface -> nx_interface_capability_flag = NX_DRIVER_CAPABILITY; +#endif /* NX_ENABLE_INTERFACE_CAPABILITY */ + + /* Return successful status. */ + driver_req_ptr -> nx_ip_driver_status = NX_SUCCESS; +} + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _nx_driver_initialize PORTABLE C */ +/* 6.1 */ +/* AUTHOR */ +/* */ +/* Yuxin Zhou, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function processing the initialize request. The processing */ +/* in this function is generic. All ethernet controller logic is to */ +/* be placed in _nx_driver_hardware_initialize. */ +/* */ +/* INPUT */ +/* */ +/* driver_req_ptr Driver command from the IP */ +/* thread */ +/* */ +/* OUTPUT */ +/* */ +/* None */ +/* */ +/* CALLS */ +/* */ +/* _nx_driver_hardware_initialize Process initialize request */ +/* */ +/* CALLED BY */ +/* */ +/* Driver entry function */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */ +/* 09-30-2020 Yuxin Zhou Modified comment(s), */ +/* resulting in version 6.1 */ +/* */ +/**************************************************************************/ +static VOID _nx_driver_initialize(NX_IP_DRIVER *driver_req_ptr) +{ + +NX_IP *ip_ptr; +NX_INTERFACE *interface_ptr; +UINT status; + + + /* Setup the IP pointer from the driver request. */ + ip_ptr = driver_req_ptr -> nx_ip_driver_ptr; + + /* Setup interface pointer. */ + interface_ptr = driver_req_ptr -> nx_ip_driver_interface; + + /* Initialize the driver's information structure. */ + + /* Default IP pointer to NULL. */ + nx_driver_information.nx_driver_information_ip_ptr = NX_NULL; + + /* Setup the driver state to not initialized. */ + nx_driver_information.nx_driver_information_state = NX_DRIVER_STATE_NOT_INITIALIZED; + + /* Setup the default packet pool for the driver's received packets. */ + nx_driver_information.nx_driver_information_packet_pool_ptr = ip_ptr -> nx_ip_default_packet_pool; + + /* Clear the deferred events for the driver. */ + nx_driver_information.nx_driver_information_deferred_events = 0; + +#ifdef NX_DIRVER_INTERNAL_TRANSMIT_QUEUE + + /* Clear the transmit queue count and head pointer. */ + nx_driver_information.nx_driver_transmit_packets_queued = 0; + nx_driver_information.nx_driver_transmit_queue_head = NX_NULL; + nx_driver_information.nx_driver_transmit_queue_tail = NX_NULL; +#endif + + /* Call the hardware-specific ethernet controller initialization. */ + status = _nx_driver_hardware_initialize(driver_req_ptr); + + /* Determine if the request was successful. */ + if (status == NX_SUCCESS) + { + + /* Successful hardware initialization. */ + + /* Setup driver information to point to IP pointer. */ + nx_driver_information.nx_driver_information_ip_ptr = driver_req_ptr -> nx_ip_driver_ptr; + + /* Setup the link maximum transfer unit. */ + interface_ptr -> nx_interface_ip_mtu_size = NX_DRIVER_ETHERNET_MTU - NX_DRIVER_ETHERNET_FRAME_SIZE; + + /* Setup the physical address of this IP instance. Increment the + physical address lsw to simulate multiple nodes hanging on the + ethernet. */ + interface_ptr -> nx_interface_physical_address_msw = + (ULONG)((_nx_driver_hardware_address[0] << 8) | (_nx_driver_hardware_address[1])); + interface_ptr -> nx_interface_physical_address_lsw = + (ULONG)((_nx_driver_hardware_address[2] << 24) | (_nx_driver_hardware_address[3] << 16) | + (_nx_driver_hardware_address[4] << 8) | (_nx_driver_hardware_address[5])); + + /* Indicate to the IP software that IP to physical mapping + is required. */ + interface_ptr -> nx_interface_address_mapping_needed = NX_TRUE; + + /* Move the driver's state to initialized. */ + nx_driver_information.nx_driver_information_state = NX_DRIVER_STATE_INITIALIZED; + + /* Indicate successful initialize. */ + driver_req_ptr -> nx_ip_driver_status = NX_SUCCESS; + } + else + { + + /* Initialization failed. Indicate that the request failed. */ + driver_req_ptr -> nx_ip_driver_status = NX_DRIVER_ERROR; + } +} + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _nx_driver_enable PORTABLE C */ +/* 6.1 */ +/* AUTHOR */ +/* */ +/* Yuxin Zhou, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function processing the initialize request. The processing */ +/* in this function is generic. All ethernet controller logic is to */ +/* be placed in _nx_driver_hardware_enable. */ +/* */ +/* INPUT */ +/* */ +/* driver_req_ptr Driver command from the IP */ +/* thread */ +/* */ +/* OUTPUT */ +/* */ +/* None */ +/* */ +/* CALLS */ +/* */ +/* _nx_driver_hardware_enable Process enable request */ +/* */ +/* CALLED BY */ +/* */ +/* Driver entry function */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */ +/* 09-30-2020 Yuxin Zhou Modified comment(s), */ +/* resulting in version 6.1 */ +/* */ +/**************************************************************************/ +static VOID _nx_driver_enable(NX_IP_DRIVER *driver_req_ptr) +{ + +UINT status; + + /* See if we can honor the NX_LINK_ENABLE request. */ + if (nx_driver_information.nx_driver_information_state < NX_DRIVER_STATE_INITIALIZED) + { + + /* Mark the request as not successful. */ + driver_req_ptr -> nx_ip_driver_status = NX_DRIVER_ERROR; + return; + } + + /* Check if it is enabled by someone already */ + if (nx_driver_information.nx_driver_information_state >= NX_DRIVER_STATE_LINK_ENABLED) + { + + /* Yes, the request has already been made. */ + driver_req_ptr -> nx_ip_driver_status = NX_ALREADY_ENABLED; + return; + } + + /* Call hardware specific enable. */ + status = _nx_driver_hardware_enable(driver_req_ptr); + + /* Was the hardware enable successful? */ + if (status == NX_SUCCESS) + { + + /* Update the driver state to link enabled. */ + nx_driver_information.nx_driver_information_state = NX_DRIVER_STATE_LINK_ENABLED; + + /* Mark request as successful. */ + driver_req_ptr -> nx_ip_driver_status = NX_SUCCESS; + + /* Mark the IP instance as link up. */ + driver_req_ptr -> nx_ip_driver_interface -> nx_interface_link_up = NX_TRUE; + } + else + { + + /* Enable failed. Indicate that the request failed. */ + driver_req_ptr -> nx_ip_driver_status = NX_DRIVER_ERROR; + } +} + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _nx_driver_disable PORTABLE C */ +/* 6.1 */ +/* AUTHOR */ +/* */ +/* Yuxin Zhou, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function processing the disable request. The processing */ +/* in this function is generic. All ethernet controller logic is to */ +/* be placed in _nx_driver_hardware_disable. */ +/* */ +/* INPUT */ +/* */ +/* driver_req_ptr Driver command from the IP */ +/* thread */ +/* */ +/* OUTPUT */ +/* */ +/* None */ +/* */ +/* CALLS */ +/* */ +/* _nx_driver_hardware_disable Process disable request */ +/* */ +/* CALLED BY */ +/* */ +/* Driver entry function */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */ +/* 09-30-2020 Yuxin Zhou Modified comment(s), */ +/* resulting in version 6.1 */ +/* */ +/**************************************************************************/ +static VOID _nx_driver_disable(NX_IP_DRIVER *driver_req_ptr) +{ + +NX_IP *ip_ptr; +UINT status; + + + /* Setup the IP pointer from the driver request. */ + ip_ptr = driver_req_ptr -> nx_ip_driver_ptr; + + /* Check if the link is enabled. */ + if (nx_driver_information.nx_driver_information_state != NX_DRIVER_STATE_LINK_ENABLED) + { + + /* The link is not enabled, so just return an error. */ + driver_req_ptr -> nx_ip_driver_status = NX_DRIVER_ERROR; + return; + } + + /* Call hardware specific disable. */ + status = _nx_driver_hardware_disable(driver_req_ptr); + + /* Was the hardware disable successful? */ + if (status == NX_SUCCESS) + { + + /* Mark the IP instance as link down. */ + ip_ptr -> nx_ip_driver_link_up = NX_FALSE; + + /* Update the driver state back to initialized. */ + nx_driver_information.nx_driver_information_state = NX_DRIVER_STATE_INITIALIZED; + + /* Mark request as successful. */ + driver_req_ptr -> nx_ip_driver_status = NX_SUCCESS; + } + else + { + + /* Disable failed, return an error. */ + driver_req_ptr -> nx_ip_driver_status = NX_DRIVER_ERROR; + } +} + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _nx_driver_packet_send PORTABLE C */ +/* 6.1 */ +/* AUTHOR */ +/* */ +/* Yuxin Zhou, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function processing the packet send request. The processing */ +/* in this function is generic. All ethernet controller packet send */ +/* logic is to be placed in _nx_driver_hardware_packet_send. */ +/* */ +/* INPUT */ +/* */ +/* driver_req_ptr Driver command from the IP */ +/* thread */ +/* */ +/* OUTPUT */ +/* */ +/* None */ +/* */ +/* CALLS */ +/* */ +/* _nx_driver_hardware_packet_send Process packet send request */ +/* */ +/* CALLED BY */ +/* */ +/* Driver entry function */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */ +/* 09-30-2020 Yuxin Zhou Modified comment(s), */ +/* resulting in version 6.1 */ +/* */ +/**************************************************************************/ +static VOID _nx_driver_packet_send(NX_IP_DRIVER *driver_req_ptr) +{ + +NX_PACKET *packet_ptr; +ULONG *ethernet_frame_ptr; +UINT status; + + + /* Check to make sure the link is up. */ + if (nx_driver_information.nx_driver_information_state != NX_DRIVER_STATE_LINK_ENABLED) + { + + /* Inidate an unsuccessful packet send. */ + driver_req_ptr -> nx_ip_driver_status = NX_DRIVER_ERROR; + + /* Link is not up, simply free the packet. */ + nx_packet_transmit_release(driver_req_ptr -> nx_ip_driver_packet); + return; + } + + /* Process driver send packet. */ + + /* Place the ethernet frame at the front of the packet. */ + packet_ptr = driver_req_ptr -> nx_ip_driver_packet; + + /* Adjust the prepend pointer. */ + packet_ptr -> nx_packet_prepend_ptr = + packet_ptr -> nx_packet_prepend_ptr - NX_DRIVER_ETHERNET_FRAME_SIZE; + + /* Adjust the packet length. */ + packet_ptr -> nx_packet_length = packet_ptr -> nx_packet_length + NX_DRIVER_ETHERNET_FRAME_SIZE; + + /* Setup the ethernet frame pointer to build the ethernet frame. Backup another 2 + * bytes to get 32-bit word alignment. */ + ethernet_frame_ptr = (ULONG *) (packet_ptr -> nx_packet_prepend_ptr - 2); + + /* Set up the hardware addresses in the Ethernet header. */ + *ethernet_frame_ptr = driver_req_ptr -> nx_ip_driver_physical_address_msw; + *(ethernet_frame_ptr + 1) = driver_req_ptr -> nx_ip_driver_physical_address_lsw; + + *(ethernet_frame_ptr + 2) = (driver_req_ptr -> nx_ip_driver_interface -> nx_interface_physical_address_msw << 16) | + (driver_req_ptr -> nx_ip_driver_interface -> nx_interface_physical_address_lsw >> 16); + *(ethernet_frame_ptr + 3) = (driver_req_ptr -> nx_ip_driver_interface -> nx_interface_physical_address_lsw << 16); + + /* Set up the frame type field in the Ethernet harder. */ + if ((driver_req_ptr -> nx_ip_driver_command == NX_LINK_ARP_SEND)|| + (driver_req_ptr -> nx_ip_driver_command == NX_LINK_ARP_RESPONSE_SEND)) + { + + *(ethernet_frame_ptr + 3) |= NX_DRIVER_ETHERNET_ARP; + } + else if(driver_req_ptr -> nx_ip_driver_command == NX_LINK_RARP_SEND) + { + + *(ethernet_frame_ptr + 3) |= NX_DRIVER_ETHERNET_RARP; + } + +#ifdef FEATURE_NX_IPV6 + else if(packet_ptr -> nx_packet_ip_version == NX_IP_VERSION_V6) + { + + *(ethernet_frame_ptr + 3) |= NX_DRIVER_ETHERNET_IPV6; + } +#endif + + else + { + + *(ethernet_frame_ptr + 3) |= NX_DRIVER_ETHERNET_IP; + } + + /* Endian swapping if NX_LITTLE_ENDIAN is defined. */ + NX_CHANGE_ULONG_ENDIAN(*(ethernet_frame_ptr)); + NX_CHANGE_ULONG_ENDIAN(*(ethernet_frame_ptr + 1)); + NX_CHANGE_ULONG_ENDIAN(*(ethernet_frame_ptr + 2)); + NX_CHANGE_ULONG_ENDIAN(*(ethernet_frame_ptr + 3)); + + /* Determine if the packet exceeds the driver's MTU. */ + if (packet_ptr -> nx_packet_length > NX_DRIVER_ETHERNET_MTU) + { + + /* This packet exceeds the size of the driver's MTU. Simply throw it away! */ + + /* Remove the Ethernet header. */ + NX_DRIVER_ETHERNET_HEADER_REMOVE(packet_ptr); + + /* Indicate an unsuccessful packet send. */ + driver_req_ptr -> nx_ip_driver_status = NX_DRIVER_ERROR; + + /* Link is not up, simply free the packet. */ + nx_packet_transmit_release(packet_ptr); + return; + } + + /* Transmit the packet through the Ethernet controller low level access routine. */ + status = _nx_driver_hardware_packet_send(packet_ptr); + + /* Determine if there was an error. */ + if (status != NX_SUCCESS) + { + + /* Driver's hardware send packet routine failed to send the packet. */ + + /* Remove the Ethernet header. */ + NX_DRIVER_ETHERNET_HEADER_REMOVE(packet_ptr); + + /* Indicate an unsuccessful packet send. */ + driver_req_ptr -> nx_ip_driver_status = NX_DRIVER_ERROR; + + /* Link is not up, simply free the packet. */ + nx_packet_transmit_release(packet_ptr); + } + else + { + + /* Set the status of the request. */ + driver_req_ptr -> nx_ip_driver_status = NX_SUCCESS; + } +} + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _nx_driver_multicast_join PORTABLE C */ +/* 6.1 */ +/* AUTHOR */ +/* */ +/* Yuxin Zhou, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function processing the multicast join request. The processing */ +/* in this function is generic. All ethernet controller multicast join */ +/* logic is to be placed in _nx_driver_hardware_multicast_join. */ +/* */ +/* INPUT */ +/* */ +/* driver_req_ptr Driver command from the IP */ +/* thread */ +/* */ +/* OUTPUT */ +/* */ +/* None */ +/* */ +/* CALLS */ +/* */ +/* _nx_driver_hardware_multicast_join Process multicast join request*/ +/* */ +/* CALLED BY */ +/* */ +/* Driver entry function */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */ +/* 09-30-2020 Yuxin Zhou Modified comment(s), */ +/* resulting in version 6.1 */ +/* */ +/**************************************************************************/ +static VOID _nx_driver_multicast_join(NX_IP_DRIVER *driver_req_ptr) +{ + +UINT status; + + + if (nx_driver_information.nx_driver_information_state >= NX_DRIVER_STATE_INITIALIZED) + { + + /* Call hardware specific multicast join function. */ + status = _nx_driver_hardware_multicast_join(driver_req_ptr); + } + else + { + + status = NX_NOT_ENABLED; + } + + /* Determine if there was an error. */ + if (status != NX_SUCCESS) + { + + /* Indicate an unsuccessful request. */ + driver_req_ptr -> nx_ip_driver_status = NX_DRIVER_ERROR; + } + else + { + + /* Indicate the request was successful. */ + driver_req_ptr -> nx_ip_driver_status = NX_SUCCESS; + } +} + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _nx_driver_multicast_leave PORTABLE C */ +/* 6.1 */ +/* AUTHOR */ +/* */ +/* Yuxin Zhou, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function processing the multicast leave request. The */ +/* processing in this function is generic. All ethernet controller */ +/* multicast leave logic is to be placed in */ +/* _nx_driver_hardware_multicast_leave. */ +/* */ +/* INPUT */ +/* */ +/* driver_req_ptr Driver command from the IP */ +/* thread */ +/* */ +/* OUTPUT */ +/* */ +/* None */ +/* */ +/* CALLS */ +/* */ +/* _nx_driver_hardware_multicast_leave Process multicast leave req */ +/* */ +/* CALLED BY */ +/* */ +/* Driver entry function */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */ +/* 09-30-2020 Yuxin Zhou Modified comment(s), */ +/* resulting in version 6.1 */ +/* */ +/**************************************************************************/ +static VOID _nx_driver_multicast_leave(NX_IP_DRIVER *driver_req_ptr) +{ + +UINT status; + + if (nx_driver_information.nx_driver_information_state >= NX_DRIVER_STATE_INITIALIZED) + { + + /* Call hardware specific multicast leave function. */ + status = _nx_driver_hardware_multicast_leave(driver_req_ptr); + } + else + { + + status = NX_NOT_ENABLED; + } + + /* Determine if there was an error. */ + if (status != NX_SUCCESS) + { + + /* Indicate an unsuccessful request. */ + driver_req_ptr -> nx_ip_driver_status = NX_DRIVER_ERROR; + } + else + { + + /* Indicate the request was successful. */ + driver_req_ptr -> nx_ip_driver_status = NX_SUCCESS; + } +} + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _nx_driver_get_status PORTABLE C */ +/* 6.1 */ +/* AUTHOR */ +/* */ +/* Yuxin Zhou, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function processing the get status request. The processing */ +/* in this function is generic. All ethernet controller get status */ +/* logic is to be placed in _nx_driver_hardware_get_status. */ +/* */ +/* INPUT */ +/* */ +/* driver_req_ptr Driver command from the IP */ +/* thread */ +/* */ +/* OUTPUT */ +/* */ +/* None */ +/* */ +/* CALLS */ +/* */ +/* _nx_driver_hardware_get_status Process get status request */ +/* */ +/* CALLED BY */ +/* */ +/* Driver entry function */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */ +/* 09-30-2020 Yuxin Zhou Modified comment(s), */ +/* resulting in version 6.1 */ +/* */ +/**************************************************************************/ +static VOID _nx_driver_get_status(NX_IP_DRIVER *driver_req_ptr) +{ + +UINT status; + + + /* Call hardware specific get status function. */ + status = _nx_driver_hardware_get_status(driver_req_ptr); + + /* Determine if there was an error. */ + if (status != NX_SUCCESS) + { + + /* Indicate an unsuccessful request. */ + driver_req_ptr -> nx_ip_driver_status = NX_DRIVER_ERROR; + } + else + { + + /* Indicate the request was successful. */ + driver_req_ptr -> nx_ip_driver_status = NX_SUCCESS; + } +} + + + +#ifdef NX_ENABLE_INTERFACE_CAPABILITY +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _nx_driver_capability_get PORTABLE C */ +/* 6.1 */ +/* AUTHOR */ +/* */ +/* Yuxin Zhou, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function processing the get capability request. */ +/* */ +/* INPUT */ +/* */ +/* driver_req_ptr Driver command from the IP */ +/* thread */ +/* */ +/* OUTPUT */ +/* */ +/* None */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* CALLED BY */ +/* */ +/* Driver entry function */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 01-01-2014 Yuxin Zhou Initial Version 5.0 */ +/* 09-30-2020 Yuxin Zhou Modified comment(s), */ +/* resulting in version 6.1 */ +/* */ +/**************************************************************************/ +static VOID _nx_driver_capability_get(NX_IP_DRIVER *driver_req_ptr) +{ + + /* Return the capability of the Ethernet controller. */ + *(driver_req_ptr -> nx_ip_driver_return_ptr) = NX_DRIVER_CAPABILITY; + + /* Return the success status. */ + driver_req_ptr -> nx_ip_driver_status = NX_SUCCESS; +} + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _nx_driver_capability_set PORTABLE C */ +/* 6.1 */ +/* AUTHOR */ +/* */ +/* Yuxin Zhou, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function processing the set capability request. */ +/* */ +/* INPUT */ +/* */ +/* driver_req_ptr Driver command from the IP */ +/* thread */ +/* */ +/* OUTPUT */ +/* */ +/* None */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* CALLED BY */ +/* */ +/* Driver entry function */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 01-01-2014 Yuxin Zhou Initial Version 5.0 */ +/* 09-30-2020 Yuxin Zhou Modified comment(s), */ +/* resulting in version 6.1 */ +/* */ +/**************************************************************************/ +static VOID _nx_driver_capability_set(NX_IP_DRIVER *driver_req_ptr) +{ + +UINT status; + + + /* Call hardware specific get status function. */ + status = _nx_driver_hardware_capability_set(driver_req_ptr); + + /* Determine if there was an error. */ + if (status != NX_SUCCESS) + { + + /* Indicate an unsuccessful request. */ + driver_req_ptr -> nx_ip_driver_status = NX_DRIVER_ERROR; + } + else + { + + /* Indicate the request was successful. */ + driver_req_ptr -> nx_ip_driver_status = NX_SUCCESS; + } +} +#endif /* NX_ENABLE_INTERFACE_CAPABILITY */ + + + +#ifdef NX_DRIVER_ENABLE_DEFERRED +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _nx_driver_deferred_processing PORTABLE C */ +/* 6.1 */ +/* AUTHOR */ +/* */ +/* Yuxin Zhou, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function processing the deferred ISR action within the context */ +/* of the IP thread. */ +/* */ +/* INPUT */ +/* */ +/* driver_req_ptr Driver command from the IP */ +/* thread */ +/* */ +/* OUTPUT */ +/* */ +/* None */ +/* */ +/* CALLS */ +/* */ +/* _nx_driver_packet_transmitted Clean up after transmission */ +/* _nx_driver_packet_received Process a received packet */ +/* */ +/* CALLED BY */ +/* */ +/* Driver entry function */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */ +/* 09-30-2020 Yuxin Zhou Modified comment(s), */ +/* resulting in version 6.1 */ +/* */ +/**************************************************************************/ +static VOID _nx_driver_deferred_processing(NX_IP_DRIVER *driver_req_ptr) +{ + +TX_INTERRUPT_SAVE_AREA + +ULONG deferred_events; + + + /* Disable interrupts. */ + TX_DISABLE + + /* Pickup deferred events. */ + deferred_events = nx_driver_information.nx_driver_information_deferred_events; + nx_driver_information.nx_driver_information_deferred_events = 0; + + /* Restore interrupts. */ + TX_RESTORE + + /* Check for a transmit complete event. */ + if(deferred_events & NX_DRIVER_DEFERRED_PACKET_TRANSMITTED) + { + + /* Process transmitted packet(s). */ + _nx_driver_hardware_packet_transmitted(); + } + + /* Check for recevied packet. */ + if(deferred_events & NX_DRIVER_DEFERRED_PACKET_RECEIVED) + { + + /* Process received packet(s). */ + _nx_driver_hardware_packet_received(); + } + + /* Mark request as successful. */ + driver_req_ptr->nx_ip_driver_status = NX_SUCCESS; +} +#endif + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _nx_driver_transfer_to_netx PORTABLE C */ +/* 6.1 */ +/* AUTHOR */ +/* */ +/* Yuxin Zhou, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function processing incoming packets. This routine would */ +/* be called from the driver-specific receive packet processing */ +/* function _nx_driver_hardware_packet_received. */ +/* */ +/* INPUT */ +/* */ +/* ip_ptr Pointer to IP protocol block */ +/* packet_ptr Packet pointer */ +/* */ +/* OUTPUT */ +/* */ +/* Error indication */ +/* */ +/* CALLS */ +/* */ +/* _nx_ip_packet_receive NetX IP packet receive */ +/* _nx_ip_packet_deferred_receive NetX IP packet receive */ +/* _nx_arp_packet_deferred_receive NetX ARP packet receive */ +/* _nx_rarp_packet_deferred_receive NetX RARP packet receive */ +/* _nx_packet_release Release packet */ +/* */ +/* CALLED BY */ +/* */ +/* _nx_driver_hardware_packet_received Driver packet receive function*/ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */ +/* 09-30-2020 Yuxin Zhou Modified comment(s), */ +/* resulting in version 6.1 */ +/* */ +/**************************************************************************/ +static VOID _nx_driver_transfer_to_netx(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ + +USHORT packet_type; + + + packet_ptr -> nx_packet_ip_interface = nx_driver_information.nx_driver_information_interface; + + /* Pickup the packet header to determine where the packet needs to be + sent. */ + packet_type = (USHORT)(((UINT) (*(packet_ptr -> nx_packet_prepend_ptr+12))) << 8) | + ((UINT) (*(packet_ptr -> nx_packet_prepend_ptr+13))); + + /* Route the incoming packet according to its ethernet type. */ + if (packet_type == NX_DRIVER_ETHERNET_IP || packet_type == NX_DRIVER_ETHERNET_IPV6) + { + /* Note: The length reported by some Ethernet hardware includes + bytes after the packet as well as the Ethernet header. In some + cases, the actual packet length after the Ethernet header should + be derived from the length in the IP header (lower 16 bits of + the first 32-bit word). */ + + /* Clean off the Ethernet header. */ + packet_ptr -> nx_packet_prepend_ptr = + packet_ptr -> nx_packet_prepend_ptr + NX_DRIVER_ETHERNET_FRAME_SIZE; + + /* Adjust the packet length. */ + packet_ptr -> nx_packet_length = + packet_ptr -> nx_packet_length - NX_DRIVER_ETHERNET_FRAME_SIZE; + + /* Route to the ip receive function. */ +#ifdef NX_DRIVER_ENABLE_DEFERRED + _nx_ip_packet_deferred_receive(ip_ptr, packet_ptr); +#else + _nx_ip_packet_receive(ip_ptr, packet_ptr); +#endif + } + else if (packet_type == NX_DRIVER_ETHERNET_ARP) + { + + /* Clean off the Ethernet header. */ + packet_ptr -> nx_packet_prepend_ptr = + packet_ptr -> nx_packet_prepend_ptr + NX_DRIVER_ETHERNET_FRAME_SIZE; + + /* Adjust the packet length. */ + packet_ptr -> nx_packet_length = + packet_ptr -> nx_packet_length - NX_DRIVER_ETHERNET_FRAME_SIZE; + + /* Route to the ARP receive function. */ + _nx_arp_packet_deferred_receive(ip_ptr, packet_ptr); + } + else if (packet_type == NX_DRIVER_ETHERNET_RARP) + { + + /* Clean off the Ethernet header. */ + packet_ptr -> nx_packet_prepend_ptr = + packet_ptr -> nx_packet_prepend_ptr + NX_DRIVER_ETHERNET_FRAME_SIZE; + + /* Adjust the packet length. */ + packet_ptr -> nx_packet_length = + packet_ptr -> nx_packet_length - NX_DRIVER_ETHERNET_FRAME_SIZE; + + /* Route to the RARP receive function. */ + _nx_rarp_packet_deferred_receive(ip_ptr, packet_ptr); + } + else + { + /* Invalid ethernet header... release the packet. */ + nx_packet_release(packet_ptr); + } +} + + +#ifdef NX_DIRVER_INTERNAL_TRANSMIT_QUEUE +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _nx_driver_transmit_packet_enqueue PORTABLE C */ +/* 6.1 */ +/* AUTHOR */ +/* */ +/* Yuxin Zhou, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function queues a transmit packet when the hardware transmit */ +/* queue does not have the resources (buffer descriptors, etc.) to */ +/* send the packet. The queue is maintained as a singularly linked- */ +/* list with head and tail pointers. The maximum number of packets on */ +/* the transmit queue is regulated by the constant */ +/* NX_DRIVER_MAX_TRANSMIT_QUEUE_DEPTH. When this number is exceeded, */ +/* the oldest packet is discarded after the new packet is queued. */ +/* */ +/* Note: that it is assumed further driver interrupts are locked out */ +/* during the call to this driver utility. */ +/* */ +/* INPUT */ +/* */ +/* packet_ptr Packet pointer */ +/* */ +/* OUTPUT */ +/* */ +/* None */ +/* */ +/* CALLS */ +/* */ +/* _nx_packet_transmit_release Release packet */ +/* */ +/* CALLED BY */ +/* */ +/* _nx_driver_hardware_packet_send Driver packet send function */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */ +/* 09-30-2020 Yuxin Zhou Modified comment(s), */ +/* resulting in version 6.1 */ +/* */ +/**************************************************************************/ +static VOID _nx_driver_transmit_packet_enqueue(NX_PACKET *packet_ptr) +{ + + /* Determine if there is anything on the queue. */ + if (nx_driver_information.nx_driver_transmit_queue_tail) + { + + /* Yes, something is on the transmit queue. Simply add the new packet to the + tail. */ + nx_driver_information.nx_driver_transmit_queue_tail -> nx_packet_queue_next = packet_ptr; + + /* Update the tail pointer. */ + nx_driver_information.nx_driver_transmit_queue_tail = packet_ptr; + } + else + { + + /* First packet on the transmit queue. */ + + /* Setup head pointers. */ + nx_driver_information.nx_driver_transmit_queue_head = packet_ptr; + nx_driver_information.nx_driver_transmit_queue_tail = packet_ptr; + + /* Set the packet's next pointer to NULL. */ + packet_ptr -> nx_packet_queue_next = NX_NULL; + } + + /* Increment the total packets queued. */ + nx_driver_information.nx_driver_transmit_packets_queued++; + + /* Determine if the total packet queued exceeds the driver's maximum transmit + queue depth. */ + if (nx_driver_information.nx_driver_transmit_packets_queued > NX_DRIVER_MAX_TRANSMIT_QUEUE_DEPTH) + { + + /* Yes, remove the head packet (oldest) packet in the transmit queue and release it. */ + packet_ptr = nx_driver_information.nx_driver_transmit_queue_head; + + /* Adjust the head pointer to the next packet. */ + nx_driver_information.nx_driver_transmit_queue_head = packet_ptr -> nx_packet_queue_next; + + /* Decrement the transmit packet queued count. */ + nx_driver_information.nx_driver_transmit_packets_queued--; + + /* Remove the ethernet header. */ + NX_DRIVER_ETHERNET_HEADER_REMOVE(packet_ptr); + + /* Release the packet. */ + nx_packet_transmit_release(packet_ptr); + } +} + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _nx_driver_transmit_packet_dequeue PORTABLE C */ +/* 6.1 */ +/* AUTHOR */ +/* */ +/* Yuxin Zhou, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function removes the oldest transmit packet when the hardware */ +/* transmit queue has new resources (usually after a transmit complete */ +/* interrupt) to send the packet. If there are no packets in the */ +/* transmit queue, a NULL is returned. */ +/* */ +/* Note: that it is assumed further driver interrupts are locked out */ +/* during the call to this driver utility. */ +/* */ +/* INPUT */ +/* */ +/* None */ +/* */ +/* OUTPUT */ +/* */ +/* packet_ptr Packet pointer */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* CALLED BY */ +/* */ +/* _nx_driver_hardware_packet_send Driver packet send function */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */ +/* 09-30-2020 Yuxin Zhou Modified comment(s), */ +/* resulting in version 6.1 */ +/* */ +/**************************************************************************/ +static NX_PACKET *_nx_driver_transmit_packet_dequeue(VOID) +{ + +NX_PACKET *packet_ptr; + + + /* Pickup the head pointer of the tranmit packet queue. */ + packet_ptr = nx_driver_information.nx_driver_transmit_queue_head; + + /* Determine if there is anything on the queue. */ + if (packet_ptr) + { + + /* Yes, something is on the transmit queue. Simply the packet from the head of the queue. */ + + /* Update the head pointer. */ + nx_driver_information.nx_driver_transmit_queue_head = packet_ptr -> nx_packet_queue_next; + + /* Clear the next pointer in the packet. */ + packet_ptr -> nx_packet_queue_next = NX_NULL; + + /* Decrement the transmit packet queued count. */ + nx_driver_information.nx_driver_transmit_packets_queued--; + } + + /* Return the packet pointer - NULL if there are no packets queued. */ + return(packet_ptr); +} + +#endif + + + +/****** DRIVER SPECIFIC ****** Start of part/vendor specific internal driver functions. */ + +typedef struct +{ + enet_mii_mode_t interface; /* Transceiver mode */ + uint8_t neg; /* FEC autoneg */ + phy_speed_t speed; /* Ethernet Speed */ + phy_duplex_t duplex; /* Ethernet Duplex */ + uint8_t mac[6]; /* Ethernet Address */ +} ENET_CONFIG_IMX; + +void enet_init_imx(ENET_CONFIG_IMX *config) +{ + /* Clear the Individual and Group Address Hash registers */ + ENET->IALR/*(ch)*/ = 0; + ENET->IAUR/*(ch)*/ = 0; + ENET->GALR/*(ch)*/ = 0; + ENET->GAUR/*(ch)*/ = 0; + + /* Set the Physical Address for the selected FEC */ + /*enet_set_address(config->ch, config->mac);*/ + ENET_SetMacAddr(ENET,config->mac); + + /* Mask all FEC interrupts */ + ENET->EIMR/*(ch)*/ = 0;/*FSL:ENET_EIMR_MASK_ALL_MASK;*/ + + /* Clear all FEC interrupt events */ + ENET->EIR/*(ch)*/ = 0xFFFFFFFF;/*FSL:ENET_EIR_CLEAR_ALL_MASK;*/ + + /* Initialize the Receive Control Register */ + ENET->RCR/*(ch)*/ = 0 + | ENET_RCR_MAX_FL(14+1500+4) /*ethernet frame head + max data+crc*/ + | ENET_RCR_MII_MODE_MASK /*always*/ + | ENET_RCR_CRCFWD_MASK; /*no CRC pad required*/ + + if ( config->interface == kENET_RmiiMode ) + { + ENET->RCR/*(ch)*/ |= ENET_RCR_RMII_MODE_MASK; + + /*only set speed in RMII mode*/ + if( config->speed == kPHY_Speed10M ) + { + ENET->RCR/*(ch)*/ |= ENET_RCR_RMII_10T_MASK; + } + }/*no need to configure MAC MII interface*/ + + ENET->TCR/*(ch)*/ = 0; + + /* Set the duplex */ + switch (config->duplex) + { + case kENET_MiiHalfDuplex: + ENET->RCR/*(ch)*/ |= ENET_RCR_DRT_MASK; + ENET->TCR/*(ch)*/ &= (uint32_t)~ENET_TCR_FDEN_MASK; + break; + case kENET_MiiFullDuplex: + default: + ENET->RCR/*(ch)*/ &= ~ENET_RCR_DRT_MASK; + ENET->TCR/*(ch)*/ |= ENET_TCR_FDEN_MASK; + break; + } + +#ifdef ENET_ENHANCEDBUFFERDESCRIPTOR_MODE + ENET->ECR/*(ch)*/ = ENET_ECR_EN1588_MASK; +#else + ENET->ECR/*(ch)*/ = 0; +#endif + + +#ifdef IMX_CHECKSUM_OFFLOAD + ENET->TACC = ENET_TACC_SHIFT16_MASK | + ENET_TACC_IPCHK_MASK | + ENET_TACC_PROCHK_MASK; + + ENET->TFWR = ENET_TFWR_STRFWD_MASK; + + ENET->RACC = ENET_RACC_SHIFT16_MASK | + ENET_RACC_LINEDIS_MASK | + ENET_RACC_PRODIS_MASK | + ENET_RACC_IPDIS_MASK; +#else + ENET->TACC = ENET_TACC_SHIFT16_MASK; + + ENET->RACC = ENET_RACC_SHIFT16_MASK | + ENET_RACC_LINEDIS_MASK; +#endif + +} +UINT enet_init() +{ + bool link = false; + phy_speed_t speed; + phy_duplex_t duplex; + uint32_t sysClock; + int32_t status; + ENET_CONFIG_IMX econf; + int32_t unique_id; + +#ifndef NX_DRIVER_ETHERNET_MAC + /*Use unique id as mac address*/ + unique_id = OCOTP->CFG0; + _nx_driver_hardware_address[2]=(UCHAR)unique_id; + _nx_driver_hardware_address[3]= (UCHAR)(unique_id >> 8); + _nx_driver_hardware_address[4]= (UCHAR)(unique_id >> 16); + _nx_driver_hardware_address[5]= (UCHAR)(unique_id >> 24); + +#ifdef NX_DEBUG + printf("MAC address : %x:%x:%x:%x:%x:%x\r\n", _nx_driver_hardware_address[0], + _nx_driver_hardware_address[1], + _nx_driver_hardware_address[2], + _nx_driver_hardware_address[3], + _nx_driver_hardware_address[4], + _nx_driver_hardware_address[5]); +#endif +#endif + + econf.interface = kENET_RmiiMode; + econf.neg = 0; /*autoneg on */ + econf.speed = kPHY_Speed100M; + econf.duplex = kPHY_FullDuplex; + econf.mac[0] = _nx_driver_hardware_address[0]; + econf.mac[1] = _nx_driver_hardware_address[1]; + econf.mac[2] = _nx_driver_hardware_address[2]; + econf.mac[3] = _nx_driver_hardware_address[3]; + econf.mac[4] = _nx_driver_hardware_address[4]; + econf.mac[5] = _nx_driver_hardware_address[5]; + + /* Set SMI to get PHY link status. */ + sysClock = CLOCK_GetFreq(kCLOCK_IpgClk); + status = PHY_Init(EXAMPLE_ENET, EXAMPLE_PHY, sysClock); + if (status != kStatus_Success) + { + status = PHY_Init(EXAMPLE_ENET, EXAMPLE_PHY, sysClock); + if (status != kStatus_Success) + { +#ifdef NX_DEBUG + printf("\r\nPHY Auto-negotiation failed. Please check the cable connection and link partner setting.\r\n"); +#endif + return(NX_DRIVER_ERROR); + } + } + + PHY_GetLinkStatus(EXAMPLE_ENET, EXAMPLE_PHY, &link); + if (link) + { + /* Get the actual PHY link speed. */ + PHY_GetLinkSpeedDuplex(EXAMPLE_ENET, EXAMPLE_PHY, &speed, &duplex); + /* Change the MII speed and duplex for actual link status. */ + econf.speed = (phy_speed_t)speed; + econf.duplex = (phy_duplex_t)duplex; + } + + enet_init_imx(&econf); + + return(NX_SUCCESS); +} + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _nx_driver_hardware_initialize PORTABLE C */ +/* 6.1 */ +/* AUTHOR */ +/* */ +/* Yuxin Zhou, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function processes hardware-specific initialization. */ +/* */ +/* INPUT */ +/* */ +/* driver_req_ptr Driver request pointer */ +/* */ +/* OUTPUT */ +/* */ +/* status [NX_SUCCESS|NX_DRIVER_ERROR] */ +/* */ +/* CALLS */ +/* */ +/* ETH_BSP_Config Configure Ethernet */ +/* ETH_MACAddressConfig Setup MAC address */ +/* ETH_DMARxDescReceiveITConfig Enable receive descriptors */ +/* nx_packet_allocate Allocate receive packet(s) */ +/* */ +/* CALLED BY */ +/* */ +/* _nx_driver_initialize Driver initialize processing */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */ +/* 09-30-2020 Yuxin Zhou Modified comment(s), */ +/* resulting in version 6.1 */ +/* */ +/**************************************************************************/ +static UINT _nx_driver_hardware_initialize(NX_IP_DRIVER *driver_req_ptr) +{ + +NX_PACKET *packet_ptr; +UINT i; + + /* Default to successful return. */ + driver_req_ptr -> nx_ip_driver_status = NX_SUCCESS; + + /* Setup indices. */ + nx_driver_information.nx_driver_information_receive_current_index = 0; + nx_driver_information.nx_driver_information_transmit_current_index = 0; + nx_driver_information.nx_driver_information_transmit_release_index = 0; + + /* Clear the number of buffers in use counter. */ + nx_driver_information.nx_driver_information_number_of_transmit_buffers_in_use = 0; + + /* Make sure there are receive packets... otherwise, return an error. */ + if (nx_driver_information.nx_driver_information_packet_pool_ptr == NULL) + { + + /* There must be receive packets. If not, return an error! */ + return(NX_DRIVER_ERROR); + } + + + if (enet_init()== NX_DRIVER_ERROR) + { + return(NX_DRIVER_ERROR); + } + + /* Initialize TX Descriptors list: Ring Mode. */ + + /* Make sure Number of Buffer Descriptors is power of 2 */ +#if (NX_DRIVER_TX_DESCRIPTORS & (NX_DRIVER_TX_DESCRIPTORS - 1)) != 0 +#error "Number of Buffer Descriptors must be power of 2" +#endif + + nx_driver_information.nx_driver_information_dma_tx_descriptors = (enet_tx_bd_struct_t*)(((UINT)nx_driver_information.nx_driver_information_dma_tx_descriptors_area + 15) & (~15)); + + /* Fill each DMATxDesc descriptor with the right values. */ + for(i = 0; i < NX_DRIVER_TX_DESCRIPTORS; i++) + { + + /* Initialize tx descriptors. */ + nx_driver_information.nx_driver_information_dma_tx_descriptors[i].control = ENET_BUFFDESCRIPTOR_TX_TRANMITCRC_MASK; + nx_driver_information.nx_driver_information_dma_tx_descriptors[i].length = 0; + +#ifdef ENET_ENHANCEDBUFFERDESCRIPTOR_MODE +#ifdef IMX_CHECKSUM_OFFLOAD + /* Enable tx interrupt & checksum offload. */ + nx_driver_information.nx_driver_information_dma_tx_descriptors[i].controlExtend1 = ENET_BUFFDESCRIPTOR_TX_INTERRUPT_MASK | 0x0800 | 0x1000; + #else + + /* Enable tx interrupt. */ + nx_driver_information.nx_driver_information_dma_tx_descriptors[i].controlExtend1 = ENET_BUFFDESCRIPTOR_TX_INTERRUPT_MASK; + #endif +#endif + nx_driver_information.nx_driver_information_transmit_packets[i] = NX_NULL; + + } + + /* Put the Wrap indicaiton on the last descriptor. */ + nx_driver_information.nx_driver_information_dma_tx_descriptors[NX_DRIVER_TX_DESCRIPTORS - 1].control |= ENET_BUFFDESCRIPTOR_TX_WRAP_MASK; + + /* Set Transmit Descriptor List Address Register */ + ENET->TDSR = (ULONG) nx_driver_information.nx_driver_information_dma_tx_descriptors; + + /* Initialize RX Descriptors list: Ring Mode */ + + /* Make sure Number of Buffer Descriptors is power of 2 */ +#if (NX_DRIVER_RX_DESCRIPTORS & (NX_DRIVER_RX_DESCRIPTORS - 1)) != 0 +#error "Number of Buffer Descriptors must be power of 2" +#endif + + nx_driver_information.nx_driver_information_dma_rx_descriptors = (enet_rx_bd_struct_t*)(((UINT)nx_driver_information.nx_driver_information_dma_rx_descriptors_area + 15) & (~15)); + + /* Fill each DMARxDesc descriptor with the right values */ + for(i = 0; i < NX_DRIVER_RX_DESCRIPTORS; i++) + { + + nx_driver_information.nx_driver_information_dma_rx_descriptors[i].length = 0; + + /* Allocate a packet for the receive buffers. */ + if (nx_packet_allocate(nx_driver_information.nx_driver_information_packet_pool_ptr, &packet_ptr, + NX_RECEIVE_PACKET, NX_NO_WAIT) == NX_SUCCESS) + { + + nx_driver_information.nx_driver_information_dma_rx_descriptors[i].control = ENET_BUFFDESCRIPTOR_RX_EMPTY_MASK; + +#ifdef ENET_ENHANCEDBUFFERDESCRIPTOR_MODE + nx_driver_information.nx_driver_information_dma_rx_descriptors[i].controlExtend2 = 0x0000; + nx_driver_information.nx_driver_information_dma_rx_descriptors[i].controlExtend1 = ENET_BUFFDESCRIPTOR_RX_BROADCAST_MASK; +#endif + nx_driver_information.nx_driver_information_dma_rx_descriptors[i].buffer = (uint8_t *)(uint32_t)packet_ptr->nx_packet_prepend_ptr; + nx_driver_information.nx_driver_information_receive_packets[i] = packet_ptr; + + } + else + { + + /* Cannot allocate packets from the packet pool. */ + return(NX_DRIVER_ERROR); + } + + } + + /* Put the Wrap indicaiton on the last descriptor. */ + nx_driver_information.nx_driver_information_dma_rx_descriptors[NX_DRIVER_RX_DESCRIPTORS - 1].control |= ENET_BUFFDESCRIPTOR_RX_WRAP_MASK | ENET_BUFFDESCRIPTOR_RX_EMPTY_MASK; + + /* Save the size of one rx buffer. */ + nx_driver_information.nx_driver_information_rx_buffer_size = packet_ptr -> nx_packet_data_end - packet_ptr -> nx_packet_data_start; + + /* Configure the Receive Buffer Size Register. */ + ENET->MRBR = nx_driver_information.nx_driver_information_rx_buffer_size; + + /* Set Receive Descriptor List Address Register. */ + ENET->RDSR = (ULONG) nx_driver_information.nx_driver_information_dma_rx_descriptors; + + for (i = 64; i; i--) + { + + nx_driver_information.nx_driver_information_multicast_count[i] = 0; + } + + /* Return success! */ + return(NX_SUCCESS); +} + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _nx_driver_hardware_enable PORTABLE C */ +/* 6.1 */ +/* AUTHOR */ +/* */ +/* Yuxin Zhou, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function processes hardware-specific link enable requests. */ +/* */ +/* INPUT */ +/* */ +/* driver_req_ptr Driver request pointer */ +/* */ +/* OUTPUT */ +/* */ +/* status [NX_SUCCESS|NX_DRIVER_ERROR] */ +/* */ +/* CALLS */ +/* */ + +/* */ +/* CALLED BY */ +/* */ +/* _nx_driver_enable Driver link enable processing */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */ +/* 09-30-2020 Yuxin Zhou Modified comment(s), */ +/* resulting in version 6.1 */ +/* */ +/**************************************************************************/ +static UINT _nx_driver_hardware_enable(NX_IP_DRIVER *driver_req_ptr) +{ + + /* Enable Ethernet interrupt. */ + ENET->EIMR = ENET_EIMR_RXF_MASK | ENET_EIMR_TXF_MASK; + /* Start Ethernet. */ + ENET->ECR |= ENET_ECR_ETHEREN_MASK; + + /*The buffer descriptor bytes are swapped to support little-endian devices.*/ + /*This field must be written to 1 after reset*/ + ENET->ECR|= ENET_ECR_DBSWP_MASK; + + + EnableIRQ(ENET_IRQn); + /*active rx descriptor*/ + ENET->RDAR = ENET_RDAR_RDAR_MASK; + /* Return success! */ + return(NX_SUCCESS); +} + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _nx_driver_hardware_disable PORTABLE C */ +/* 6.1 */ +/* AUTHOR */ +/* */ +/* Yuxin Zhou, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function processes hardware-specific link disable requests. */ +/* */ +/* INPUT */ +/* */ +/* driver_req_ptr Driver request pointer */ +/* */ +/* OUTPUT */ +/* */ +/* status [NX_SUCCESS|NX_DRIVER_ERROR] */ +/* */ +/* CALLS */ +/* */ + +/* */ +/* CALLED BY */ +/* */ +/* _nx_driver_disable Driver link disable processing*/ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */ +/* 09-30-2020 Yuxin Zhou Modified comment(s), */ +/* resulting in version 6.1 */ +/* */ +/**************************************************************************/ +static UINT _nx_driver_hardware_disable(NX_IP_DRIVER *driver_req_ptr) +{ + + /* Stop the Ethernet. */ + ENET->ECR &= ~ENET_ECR_ETHEREN_MASK; + + + /* Return success! */ + return(NX_SUCCESS); +} + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _nx_driver_hardware_packet_send PORTABLE C */ +/* 6.1 */ +/* AUTHOR */ +/* */ +/* Yuxin Zhou, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function processes hardware-specific packet send requests. */ +/* */ +/* INPUT */ +/* */ +/* packet_ptr Pointer to packet to send */ +/* */ +/* OUTPUT */ +/* */ +/* status [NX_SUCCESS|NX_DRIVER_ERROR] */ +/* */ +/* CALLS */ +/* */ +/* [_nx_driver_transmit_packet_enqueue] Optional internal transmit */ +/* packet queue routine */ +/* */ +/* CALLED BY */ +/* */ +/* _nx_driver_packet_send Driver packet send processing */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */ +/* 09-30-2020 Yuxin Zhou Modified comment(s), */ +/* resulting in version 6.1 */ +/* */ +/**************************************************************************/ +static UINT _nx_driver_hardware_packet_send(NX_PACKET *packet_ptr) +{ + +ULONG curIdx; +NX_PACKET *pktIdx; +ULONG bd_count = 0; +UCHAR remainder = 0; +UCHAR* src_addr; + + /* Pick up the first BD. */ + curIdx = nx_driver_information.nx_driver_information_transmit_current_index; + + /* Check if it is a free descriptor. */ + if ((nx_driver_information.nx_driver_information_dma_tx_descriptors[curIdx].control & ENET_BUFFDESCRIPTOR_TX_READY_MASK) || nx_driver_information.nx_driver_information_transmit_packets[curIdx]) + { + /* Buffer is still owned by device. */ + return(NX_DRIVER_ERROR); + } + /* Set the buffer size. */ + nx_driver_information.nx_driver_information_dma_tx_descriptors[curIdx].length = (packet_ptr -> nx_packet_append_ptr - packet_ptr->nx_packet_prepend_ptr + 2); + + remainder = (UCHAR )((ULONG)(packet_ptr->nx_packet_prepend_ptr - 2)& 0x07); + + if(remainder) + { + src_addr = packet_ptr->nx_packet_prepend_ptr; + + /*make sure transmit BD buffer 8byte aligment*/ + packet_ptr->nx_packet_prepend_ptr -= remainder; + + memmove(packet_ptr->nx_packet_prepend_ptr,src_addr,nx_driver_information.nx_driver_information_dma_tx_descriptors[curIdx].length); + } + + /* Find the Buffer, set the Buffer pointer. */ + nx_driver_information.nx_driver_information_dma_tx_descriptors[curIdx].buffer = (uint8_t *)(ULONG)(packet_ptr->nx_packet_prepend_ptr - 2); + + /* Clear the first Descriptor's LS bit. */ + nx_driver_information.nx_driver_information_dma_tx_descriptors[curIdx].control &= ~ENET_BUFFDESCRIPTOR_TX_LAST_MASK; + + /* Find next packet. */ + for (pktIdx = packet_ptr -> nx_packet_next; + pktIdx != NX_NULL; + pktIdx = pktIdx -> nx_packet_next) + { + + /* Move to next descriptor. */ + curIdx = (curIdx + 1) & (NX_DRIVER_TX_DESCRIPTORS - 1); + + /* Check if it is a free descriptor. */ + if ((nx_driver_information.nx_driver_information_dma_tx_descriptors[curIdx].control & ENET_BUFFDESCRIPTOR_TX_READY_MASK) || nx_driver_information.nx_driver_information_transmit_packets[curIdx]) + { + + /* No more descriptor available, return driver error status. */ + return(NX_DRIVER_ERROR); + } + + + /* Find the Buffer, set the Buffer pointer. */ + nx_driver_information.nx_driver_information_dma_tx_descriptors[curIdx].buffer = (uint8_t *)(ULONG)(pktIdx->nx_packet_prepend_ptr); + + /* Set the buffer size. */ + nx_driver_information.nx_driver_information_dma_tx_descriptors[curIdx].length = (pktIdx -> nx_packet_append_ptr - pktIdx->nx_packet_prepend_ptr); + + /* Clear the descriptor's LS bit. */ + nx_driver_information.nx_driver_information_dma_tx_descriptors[curIdx].control &= ~ENET_BUFFDESCRIPTOR_TX_LAST_MASK; + + /* Increment the BD count. */ + bd_count++; + + } + + /* Set the last Descriptor's LS & IC & OWN bit. */ + nx_driver_information.nx_driver_information_dma_tx_descriptors[curIdx].control |= (ENET_BUFFDESCRIPTOR_TX_LAST_MASK | ENET_BUFFDESCRIPTOR_TX_READY_MASK); + + /* Save the pkt pointer to release. */ + nx_driver_information.nx_driver_information_transmit_packets[curIdx] = packet_ptr; + + /* Set the current index to the next descriptor. */ + nx_driver_information.nx_driver_information_transmit_current_index = (curIdx + 1) & (NX_DRIVER_TX_DESCRIPTORS - 1); + + /* Increment the transmit buffers in use count. */ + nx_driver_information.nx_driver_information_number_of_transmit_buffers_in_use += bd_count + 1; + + /* Set OWN bit to indicate BDs are ready. */ + for (; bd_count > 0; bd_count--) + { + + /* Set OWN bit in reverse order, move to prevous BD. */ + curIdx = (curIdx - 1) & (NX_DRIVER_TX_DESCRIPTORS - 1); + + /* Set this BD's OWN bit. */ + nx_driver_information.nx_driver_information_dma_tx_descriptors[curIdx].control |= ENET_BUFFDESCRIPTOR_TX_READY_MASK; + } + + /* If the DMA transmission is suspended, resume transmission. */ + if (!ENET->TDAR) + { + + /* Resume DMA transmission. */ + ENET->TDAR = ENET_TDAR_TDAR_MASK; + } + + return(NX_SUCCESS); +} + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* nx_crc32() PORTABLE C */ +/* 6.1 */ +/* AUTHOR */ +/* */ +/* Yuxin Zhou, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* Calculate 32bit CRC using reversed Poly for Ethernet. */ +/* */ +/* INPUT */ +/* */ +/* UCHAR dbuf[] - pointer to the data buffer. */ +/* INT length - Length of the data */ +/* */ +/* OUTPUT */ +/* */ +/* CRC value */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* CALLED BY */ +/* */ +/* _nx_driver_hardware_multicast_join */ +/* _nx_driver_hardware_multicast_leave */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */ +/* 09-30-2020 Yuxin Zhou Modified comment(s), */ +/* resulting in version 6.1 */ +/* */ +/**************************************************************************/ +static ULONG nx_crc32(UCHAR dbuf[], INT length) +{ + +INT i; +INT bit; +ULONG crc = 0xFFFFFFFFUL; +ULONG poly = 0xEDB88320UL; +ULONG p; +ULONG data; + + + for (i = 0; i < length; i++) + { + data = ((ULONG)dbuf[i]); + + for (bit = 0; bit < 8; bit++) + { + p = (crc ^ ((ULONG)data)) & 1UL; + crc >>= 1; + if (p != 0) + crc ^= poly; + data >>= 1; + } + } + + return ~crc; +} /* nx_crc32 */ + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _nx_driver_hardware_multicast_join PORTABLE C */ +/* 6.1 */ +/* AUTHOR */ +/* */ +/* Yuxin Zhou, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function processes hardware-specific multicast join requests. */ +/* */ +/* INPUT */ +/* */ +/* driver_req_ptr Driver request pointer */ +/* */ +/* OUTPUT */ +/* */ +/* status [NX_SUCCESS|NX_DRIVER_ERROR] */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* CALLED BY */ +/* */ +/* _nx_driver_multicast_join Driver multicast join */ +/* processing */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */ +/* 09-30-2020 Yuxin Zhou Modified comment(s), */ +/* resulting in version 6.1 */ +/* */ +/**************************************************************************/ +static UINT _nx_driver_hardware_multicast_join(NX_IP_DRIVER *driver_req_ptr) +{ + +UCHAR adr[NX_DRIVER_PHYSICAL_ADDRESS_SIZE] ; +INT h_val; +ULONG crc_val; + + + /* Set up the array to pass to the hash_value function. */ + adr[0] = (UCHAR) (driver_req_ptr ->nx_ip_driver_physical_address_msw >> 8); + adr[1] = (UCHAR) (driver_req_ptr ->nx_ip_driver_physical_address_msw); + adr[2] = (UCHAR) (driver_req_ptr ->nx_ip_driver_physical_address_lsw >> 24); + adr[3] = (UCHAR) (driver_req_ptr ->nx_ip_driver_physical_address_lsw >> 16); + adr[4] = (UCHAR) (driver_req_ptr ->nx_ip_driver_physical_address_lsw >> 8); + adr[5] = (UCHAR) (driver_req_ptr ->nx_ip_driver_physical_address_lsw); + + /* Get the CRC done. */ + crc_val = nx_crc32(adr, NX_DRIVER_PHYSICAL_ADDRESS_SIZE); + + /* Use only 6 MSbs to obtain value in range 0..63. */ + crc_val >>= (32 - 6); + h_val = 63 - (int) crc_val ; /* pointer to 48 bit address */ + + if(nx_driver_information.nx_driver_information_multicast_count[h_val] == 255) + { + + return NX_NO_MORE_ENTRIES; + } + + nx_driver_information.nx_driver_information_multicast_count[h_val]++; + + if (h_val < 32) + ENET->GALR |= 1 << h_val; + else + ENET->GAUR |= 1 << (h_val - 32); + + /* Return success. */ + return(NX_SUCCESS); +} + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _nx_driver_hardware_multicast_leave PORTABLE C */ +/* 6.1 */ +/* AUTHOR */ +/* */ +/* Yuxin Zhou, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function processes hardware-specific multicast leave requests. */ +/* */ +/* INPUT */ +/* */ +/* driver_req_ptr Driver request pointer */ +/* */ +/* OUTPUT */ +/* */ +/* status [NX_SUCCESS|NX_DRIVER_ERROR] */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* CALLED BY */ +/* */ +/* _nx_driver_multicast_leave Driver multicast leave */ +/* processing */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */ +/* 09-30-2020 Yuxin Zhou Modified comment(s), */ +/* resulting in version 6.1 */ +/* */ +/**************************************************************************/ +static UINT _nx_driver_hardware_multicast_leave(NX_IP_DRIVER *driver_req_ptr) +{ + +UCHAR adr[NX_DRIVER_PHYSICAL_ADDRESS_SIZE] ; +INT h_val; +ULONG crc_val; + + + /* Set up the array to pass to the hash_value function. */ + adr[0] = (UCHAR) (driver_req_ptr ->nx_ip_driver_physical_address_msw >> 8); + adr[1] = (UCHAR) (driver_req_ptr ->nx_ip_driver_physical_address_msw); + adr[2] = (UCHAR) (driver_req_ptr ->nx_ip_driver_physical_address_lsw >> 24); + adr[3] = (UCHAR) (driver_req_ptr ->nx_ip_driver_physical_address_lsw >> 16); + adr[4] = (UCHAR) (driver_req_ptr ->nx_ip_driver_physical_address_lsw >> 8); + adr[5] = (UCHAR) (driver_req_ptr ->nx_ip_driver_physical_address_lsw); + + /* Get the CRC done. */ + crc_val = nx_crc32(adr, NX_DRIVER_PHYSICAL_ADDRESS_SIZE); + + /* Use only 6 MSbs to obtain value in range 0..63. */ + crc_val >>= (32 - 6); + h_val = 63 - (int) crc_val ; /* pointer to 48 bit address */ + + if(nx_driver_information.nx_driver_information_multicast_count[h_val] == 1) + { + + if (h_val < 32) + ENET->GALR &= ~(1 << h_val); + else + ENET->GAUR &= ~(1 << (h_val - 32)); + } + else if(nx_driver_information.nx_driver_information_multicast_count[h_val] == 0) + { + + return NX_NOT_SUCCESSFUL; + } + + nx_driver_information.nx_driver_information_multicast_count[h_val]--; + + /* Return success. */ + return(NX_SUCCESS); +} + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _nx_driver_hardware_get_status PORTABLE C */ +/* 6.1 */ +/* AUTHOR */ +/* */ +/* Yuxin Zhou, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function processes hardware-specific get status requests. */ +/* */ +/* INPUT */ +/* */ +/* driver_req_ptr Driver request pointer */ +/* */ +/* OUTPUT */ +/* */ +/* status [NX_SUCCESS|NX_DRIVER_ERROR] */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* CALLED BY */ +/* */ +/* _nx_driver_get_status Driver get status processing */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */ +/* 09-30-2020 Yuxin Zhou Modified comment(s), */ +/* resulting in version 6.1 */ +/* */ +/**************************************************************************/ +static UINT _nx_driver_hardware_get_status(NX_IP_DRIVER *driver_req_ptr) +{ + + *(driver_req_ptr -> nx_ip_driver_return_ptr) = driver_req_ptr -> nx_ip_driver_interface -> nx_interface_link_up; + /* Return success. */ + return(NX_SUCCESS); +} + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _nx_driver_hardware_packet_transmitted PORTABLE C */ +/* 6.1 */ +/* AUTHOR */ +/* */ +/* Yuxin Zhou, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function processes packets transmitted by the ethernet */ +/* controller. */ +/* */ +/* INPUT */ +/* */ +/* None */ +/* */ +/* OUTPUT */ +/* */ +/* None */ +/* */ +/* CALLS */ +/* */ +/* nx_packet_transmit_release Release transmitted packet */ +/* [_nx_driver_transmit_packet_dequeue] Optional transmit packet */ +/* dequeue */ +/* */ +/* CALLED BY */ +/* */ +/* _nx_driver_deferred_processing Deferred driver processing */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */ +/* 09-30-2020 Yuxin Zhou Modified comment(s), */ +/* resulting in version 6.1 */ +/* */ +/**************************************************************************/ +static VOID _nx_driver_hardware_packet_transmitted(VOID) +{ + +ULONG numOfBuf = nx_driver_information.nx_driver_information_number_of_transmit_buffers_in_use; +ULONG idx = nx_driver_information.nx_driver_information_transmit_release_index; + + + /* Loop through buffers in use. */ + while (numOfBuf--) + { + + /* If no packet, just examine the next packet. */ + if (nx_driver_information.nx_driver_information_transmit_packets[idx] == NX_NULL) + { + + /* No packet in use, skip to next. */ + idx = (idx + 1) & (NX_DRIVER_TX_DESCRIPTORS - 1); + continue; + } + + /* Determine if the packet has been transmitted. */ + if ((nx_driver_information.nx_driver_information_dma_tx_descriptors[idx].control & ENET_BUFFDESCRIPTOR_TX_READY_MASK) == 0) + { + + /* Yes, packet has been transmitted. */ + + /* Remove the Ethernet header and release the packet. */ + NX_DRIVER_ETHERNET_HEADER_REMOVE(nx_driver_information.nx_driver_information_transmit_packets[idx]); + + /* Release the packet. */ + nx_packet_transmit_release(nx_driver_information.nx_driver_information_transmit_packets[idx]); + + /* Clear the entry in the in-use array. */ + nx_driver_information.nx_driver_information_transmit_packets[idx] = NX_NULL; + + /* Update the transmit relesae index and number of buffers in use. */ + idx = (idx + 1) & (NX_DRIVER_TX_DESCRIPTORS - 1); + nx_driver_information.nx_driver_information_number_of_transmit_buffers_in_use = numOfBuf; + nx_driver_information.nx_driver_information_transmit_release_index = idx; + } + else + { + + /* Get out of the loop! */ + break; + } + } +} + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _nx_driver_hardware_packet_received PORTABLE C */ +/* 6.1 */ +/* AUTHOR */ +/* */ +/* Yuxin Zhou, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function processes packets received by the ethernet */ +/* controller. */ +/* */ +/* INPUT */ +/* */ +/* None */ +/* */ +/* OUTPUT */ +/* */ +/* None */ +/* */ +/* CALLS */ +/* */ +/* _nx_driver_transfer_to_netx Transfer packet to NetX */ +/* nx_packet_allocate Allocate receive packets */ +/* nx_packet_release Release receive packets */ +/* */ +/* CALLED BY */ +/* */ +/* _nx_driver_deferred_processing Deferred driver processing */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */ +/* 09-30-2020 Yuxin Zhou Modified comment(s), */ +/* resulting in version 6.1 */ +/* */ +/**************************************************************************/ +static VOID _nx_driver_hardware_packet_received(VOID) +{ + +NX_PACKET *packet_ptr; +ULONG bd_count = 0; +INT i; +ULONG idx; +ULONG temp_idx; +ULONG first_idx = nx_driver_information.nx_driver_information_receive_current_index; +NX_PACKET *received_packet_ptr = nx_driver_information.nx_driver_information_receive_packets[first_idx]; + + + /* Find out the BDs that owned by CPU. */ + for (first_idx = idx = nx_driver_information.nx_driver_information_receive_current_index; + (nx_driver_information.nx_driver_information_dma_rx_descriptors[idx].control & ENET_BUFFDESCRIPTOR_RX_EMPTY_MASK) == 0; + idx = (idx + 1) & (NX_DRIVER_RX_DESCRIPTORS - 1)) + { + + /* Is the BD marked as the end of a frame? */ + if (nx_driver_information.nx_driver_information_dma_rx_descriptors[idx].control & ENET_BUFFDESCRIPTOR_RX_LAST_MASK) + { + + /* Yes, this BD is the last BD in the frame, set the last NX_PACKET's nx_packet_next to NULL. */ + nx_driver_information.nx_driver_information_receive_packets[idx] -> nx_packet_next = NX_NULL; + + /* Store the length of the packet in the first NX_PACKET. */ + + nx_driver_information.nx_driver_information_receive_packets[first_idx] -> nx_packet_length = (nx_driver_information.nx_driver_information_dma_rx_descriptors[idx].length) - 2; + + nx_driver_information.nx_driver_information_receive_packets[first_idx] -> nx_packet_prepend_ptr += 2; + + /* Adjust nx_packet_append_ptr with the size of the data in this buffer. */ + nx_driver_information.nx_driver_information_receive_packets[idx] -> nx_packet_append_ptr = nx_driver_information.nx_driver_information_receive_packets[idx]->nx_packet_prepend_ptr + + nx_driver_information.nx_driver_information_receive_packets[first_idx]->nx_packet_length + - bd_count * nx_driver_information.nx_driver_information_rx_buffer_size + + (bd_count > 0 ? 2 : 0); + + /* Allocate new NX_PACKETs for BDs. */ + for (i = bd_count; i >= 0; i--) + { + + temp_idx = (first_idx + i) & (NX_DRIVER_RX_DESCRIPTORS - 1); + + /* Allocate a new packet from the packet pool. */ + if (nx_packet_allocate(nx_driver_information.nx_driver_information_packet_pool_ptr, &packet_ptr, + NX_RECEIVE_PACKET, NX_NO_WAIT) == NX_SUCCESS) + { + + /* Adjust the new packet and assign it to the BD. */ + + nx_driver_information.nx_driver_information_dma_rx_descriptors[temp_idx].buffer = (uint8_t *)((uint32_t)packet_ptr->nx_packet_prepend_ptr); + nx_driver_information.nx_driver_information_dma_rx_descriptors[temp_idx].control |= ENET_BUFFDESCRIPTOR_RX_EMPTY_MASK; + nx_driver_information.nx_driver_information_receive_packets[temp_idx] = packet_ptr; + } + else + { + + /* Allocation failed, get out of the loop. */ + break; + } + } + + if (i >= 0) + { + + /* At least one packet allocation was failed, release the received packet. */ + nx_packet_release(nx_driver_information.nx_driver_information_receive_packets[temp_idx] -> nx_packet_next); + + for (; i >= 0; i--) + { + + /* Free up the BD to ready state. */ + temp_idx = (first_idx + i) & (NX_DRIVER_RX_DESCRIPTORS - 1); + nx_driver_information.nx_driver_information_dma_rx_descriptors[temp_idx].control |= ENET_BUFFDESCRIPTOR_RX_EMPTY_MASK; + nx_driver_information.nx_driver_information_receive_packets[temp_idx] -> nx_packet_prepend_ptr = nx_driver_information.nx_driver_information_receive_packets[temp_idx] -> nx_packet_data_start; + } + } + else + { + + /* Transfer the packet to NetX. */ + _nx_driver_transfer_to_netx(nx_driver_information.nx_driver_information_ip_ptr, received_packet_ptr); + } + + /* Set the first BD index for the next packet. */ + first_idx = (idx + 1) & (NX_DRIVER_RX_DESCRIPTORS - 1); + + /* Update the current receive index. */ + nx_driver_information.nx_driver_information_receive_current_index = first_idx; + + received_packet_ptr = nx_driver_information.nx_driver_information_receive_packets[first_idx]; + + bd_count = 0; + + } + else + { + + /* This BD is not the last BD of a frame. It is a intermediate descriptor. */ + + nx_driver_information.nx_driver_information_receive_packets[idx] -> nx_packet_next = nx_driver_information.nx_driver_information_receive_packets[(idx + 1) & (NX_DRIVER_RX_DESCRIPTORS - 1)]; + + nx_driver_information.nx_driver_information_receive_packets[idx] -> nx_packet_append_ptr = nx_driver_information.nx_driver_information_receive_packets[idx] -> nx_packet_data_end; + + bd_count++; + } + } + + /* If Rx DMA is in suspended state, resume it. */ + if (!ENET->RDAR) + { + + /* Resume DMA reception */ + ENET->RDAR = ENET_RDAR_RDAR_MASK; + } + +} + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* nx_driver_link_mode_changed PORTABLE C */ +/* 6.1 */ +/* AUTHOR */ +/* */ +/* Yuxin Zhou, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function changes the link mode of the Ethernet. */ +/* */ +/* INPUT */ +/* */ +/* None */ +/* */ +/* OUTPUT */ +/* */ +/* None */ +/* */ +/* CALLS */ +/* */ +/* enet_duplex Set duplex mode */ +/* nx_packet_transmit_release Release the packet */ +/* */ +/* CALLED BY */ +/* */ +/* nx_driver_ethernet_phy_isr */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */ +/* 09-30-2020 Yuxin Zhou Modified comment(s), */ +/* resulting in version 6.1 */ +/* */ +/**************************************************************************/ +VOID nx_driver_link_mode_changed(VOID) +{ + +ULONG numOfBuf; +ULONG idx; + + + /* Stop the Ethernet. */ + ENET->ECR &= ~ENET_ECR_ETHEREN_MASK; + + /* Set speed for RMII mode. */ + if (nx_driver_information.nx_driver_information_link_speed == kENET_MiiSpeed10M) + { + + ENET->RCR |= ENET_RCR_RMII_10T_MASK; + } + else + { + + ENET->RCR &= ~ENET_RCR_RMII_10T_MASK; + } + + /* Set duplex mode. */ + /* Set the duplex on the selected FEC controller*/ + switch (nx_driver_information.nx_driver_information_link_duplex) + { + case kENET_MiiHalfDuplex: + ENET->RCR/*(ch)*/ |= ENET_RCR_DRT_MASK; + ENET->TCR/*(ch)*/ &= (uint32_t)~ENET_TCR_FDEN_MASK; + break; + case kENET_MiiFullDuplex: + default: + ENET->RCR/*(ch)*/ &= ~ENET_RCR_DRT_MASK; + ENET->TCR/*(ch)*/ |= ENET_TCR_FDEN_MASK; + break; + } + + if (nx_driver_information.nx_driver_information_state >= NX_DRIVER_STATE_INITIALIZED) + { + + numOfBuf = nx_driver_information.nx_driver_information_number_of_transmit_buffers_in_use; + idx = nx_driver_information.nx_driver_information_transmit_release_index; + + /* Reset indices. */ + nx_driver_information.nx_driver_information_receive_current_index = 0; + nx_driver_information.nx_driver_information_transmit_current_index = 0; + nx_driver_information.nx_driver_information_transmit_release_index = 0; + nx_driver_information.nx_driver_information_number_of_transmit_buffers_in_use = 0; + + /* Release transmit packets if any. */ + while (numOfBuf--) + { + + /* If no packet, just examine the next packet. */ + if (nx_driver_information.nx_driver_information_transmit_packets[idx] == NX_NULL) + { + + /* No packet in use, skip to next. */ + idx = (idx + 1) & (NX_DRIVER_TX_DESCRIPTORS - 1); + continue; + } + + /* Remove the Ethernet header and release the packet. */ + NX_DRIVER_ETHERNET_HEADER_REMOVE(nx_driver_information.nx_driver_information_transmit_packets[idx]); + + /* Release the packet. */ + nx_packet_transmit_release(nx_driver_information.nx_driver_information_transmit_packets[idx]); + } + + /* Free receive descriptors. */ + for (idx = 0; idx < NX_DRIVER_RX_DESCRIPTORS; idx++) + { + + nx_driver_information.nx_driver_information_dma_rx_descriptors[idx].control |= ENET_BUFFDESCRIPTOR_RX_EMPTY_MASK; + } + } + + /* Set Transmit Descriptor List Address Register */ + ENET->TDSR = (ULONG) nx_driver_information.nx_driver_information_dma_tx_descriptors; + + /* Configure the Receive Buffer Size Register. */ + ENET->MRBR = nx_driver_information.nx_driver_information_rx_buffer_size; + + /* Set Receive Descriptor List Address Register. */ + ENET->RDSR = (ULONG) nx_driver_information.nx_driver_information_dma_rx_descriptors; + + if (nx_driver_information.nx_driver_information_state >= NX_DRIVER_STATE_LINK_ENABLED) + { + + /* Enable ethernet & start packet receiving. */ + ENET->ECR |= ENET_ECR_ETHEREN_MASK; + ENET->RDAR = ENET_RDAR_RDAR_MASK; + } +} + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* nx_driver_imx6ul_ethernet_isr PORTABLE C */ +/* 6.1 */ +/* AUTHOR */ +/* */ +/* Yuxin Zhou, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function processing incoming packets. This routine is */ +/* be called from the receive packet ISR and assumes that the */ +/* interrupt is saved/restored around the call by ThreadX. */ +/* */ +/* INPUT */ +/* */ +/* None */ +/* */ +/* OUTPUT */ +/* */ +/* None */ +/* */ +/* CALLS */ +/* */ +/* _nx_ip_driver_deferred_processing IP receive packet processing */ +/* */ +/* CALLED BY */ +/* */ +/* ISR */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */ +/* 09-30-2020 Yuxin Zhou Modified comment(s), */ +/* resulting in version 6.1 */ +/* */ +/**************************************************************************/ +VOID nx_driver_imx_ethernet_isr(VOID) +{ +UINT status; + status = ENET->EIR; + + if(status & ENET_EIR_RXF_MASK ) + { + /* Receive packet interrupt. */ +#ifdef NX_DRIVER_ENABLE_DEFERRED + + /* Set the receive packet interrupt. */ + nx_driver_information.nx_driver_information_deferred_events |= NX_DRIVER_DEFERRED_PACKET_RECEIVED; +#else + + /* Process received packet(s). */ + _nx_driver_hardware_packet_received(); +#endif + + +#ifdef NX_DRIVER_ENABLE_DEFERRED + + /* Call NetX deferred driver processing. */ + _nx_ip_driver_deferred_processing(nx_driver_information.nx_driver_information_ip_ptr); +#endif + + /* Clear the Ethernet DMA Rx IT pending bits */ + ENET->EIR = ENET_EIR_RXF_MASK; + } + if(status & ENET_EIR_TXF_MASK) + { + + ENET->TDAR = ENET_TDAR_TDAR_MASK; + +#ifdef NX_DRIVER_ENABLE_DEFERRED + + /* Set the transmit complete bit. */ + nx_driver_information.nx_driver_information_deferred_events |= NX_DRIVER_DEFERRED_PACKET_TRANSMITTED; +#else + + /* Process transmitted packet(s). */ + _nx_driver_hardware_packet_transmitted(); +#endif + +#ifdef NX_DRIVER_ENABLE_DEFERRED + + /* Call NetX deferred driver processing. */ + _nx_ip_driver_deferred_processing(nx_driver_information.nx_driver_information_ip_ptr); +#endif + + /* Clear the Eth DMA Tx IT pending bit. */ + ENET->EIR = ENET_EIR_TXF_MASK; + } +} + +/****** DRIVER SPECIFIC ****** Start of part/vendor specific internal driver functions. */ diff --git a/targets/NXP/MIMXRT1064-EVK/lib/netx_driver/nx_driver_imxrt1062.h b/targets/NXP/MIMXRT1064-EVK/lib/netx_driver/nx_driver_imxrt1062.h new file mode 100644 index 00000000..23d30cbc --- /dev/null +++ b/targets/NXP/MIMXRT1064-EVK/lib/netx_driver/nx_driver_imxrt1062.h @@ -0,0 +1,244 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) Microsoft Corporation. All rights reserved. */ +/* */ +/* This software is licensed under the Microsoft Software License */ +/* Terms for Microsoft Azure RTOS. Full text of the license can be */ +/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */ +/* and in the root directory of this software. */ +/* */ +/**************************************************************************/ + + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** NetX Component */ +/** */ +/** Ethernet driver for IMX family of microprocessors */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +#ifndef NX_DRIVER_IMXRT1062_H +#define NX_DRIVER_IMXRT1062_H + + +#ifdef __cplusplus + +/* Yes, C++ compiler is present. Use standard C. */ +extern "C" { +#endif + + +/* Include ThreadX header file, if not already. */ + +#ifndef TX_API_H +#include "tx_api.h" +#endif + + +/* Include NetX header file, if not already. */ + +#ifndef NX_API_H +#include "nx_api.h" +#endif + + +/* Determine if the driver's source file is being compiled. The constants and typdefs are only valid within + the driver's source file compilation. */ + +#ifdef NX_DRIVER_SOURCE + + +/****** DRIVER SPECIFIC ****** Start of part/vendor specific include area. Include any such files here! */ + +#include "fsl_enet.h" +#include "fsl_phy.h" +#include "board.h" +#include "fsl_debug_console.h" + +#include "pin_mux.h" +#include "fsl_common.h" +#include "fsl_iomuxc.h" +#include "MIMXRT1062.h" + +/****** DRIVER SPECIFIC ****** End of part/vendor specific include file area! */ + + +#define CORE_CLK_FREQ CLOCK_GetFreq(kCLOCK_AhbClk) +#define EXAMPLE_ENET ENET +#define EXAMPLE_PHY 0x02U + +/*ARM Cortex M4 implementation for interrupt priority shift*/ +#define ARM_INTERRUPT_LEVEL_BITS 4 +#define PRIORITY 6 + +/* Define generic constants and macros for all NetX Ethernet drivers. */ + +#define NX_DRIVER_ETHERNET_IP 0x0800 +#define NX_DRIVER_ETHERNET_IPV6 0x86dd +#define NX_DRIVER_ETHERNET_ARP 0x0806 +#define NX_DRIVER_ETHERNET_RARP 0x8035 + +#define NX_DRIVER_ETHERNET_MTU 1514 +#define NX_DRIVER_ETHERNET_FRAME_SIZE 14 +#define NX_DRIVER_PHYSICAL_ADDRESS_SIZE 6 + +#define NX_DRIVER_DEFERRED_PACKET_RECEIVED 1 +#define NX_DRIVER_DEFERRED_DEVICE_RESET 2 +#define NX_DRIVER_DEFERRED_PACKET_TRANSMITTED 4 + +#define NX_DRIVER_STATE_NOT_INITIALIZED 1 +#define NX_DRIVER_STATE_INITIALIZE_FAILED 2 +#define NX_DRIVER_STATE_INITIALIZED 3 +#define NX_DRIVER_STATE_LINK_ENABLED 4 + +#ifdef NX_DIRVER_INTERNAL_TRANSMIT_QUEUE +#define NX_DRIVER_MAX_TRANSMIT_QUEUE_DEPTH 10 +#endif + +#define NX_DRIVER_ERROR 90 + + +#define NX_DRIVER_ETHERNET_HEADER_REMOVE(p) \ +{ \ + p -> nx_packet_prepend_ptr = p -> nx_packet_prepend_ptr + NX_DRIVER_ETHERNET_FRAME_SIZE; \ + p -> nx_packet_length = p -> nx_packet_length - NX_DRIVER_ETHERNET_FRAME_SIZE; \ +} + + +/*calculate checksum by hardware*/ + +/* +#define NX_DRIVER_CAPABILITY ( NX_INTERFACE_CAPABILITY_IPV4_TX_CHECKSUM | \ + NX_INTERFACE_CAPABILITY_IPV4_RX_CHECKSUM |\ + NX_INTERFACE_CAPABILITY_TCP_TX_CHECKSUM | \ + NX_INTERFACE_CAPABILITY_TCP_RX_CHECKSUM | \ + NX_INTERFACE_CAPABILITY_UDP_TX_CHECKSUM | \ + NX_INTERFACE_CAPABILITY_UDP_RX_CHECKSUM| \ + NX_INTERFACE_CAPABILITY_ICMPV4_TX_CHECKSUM | \ + NX_INTERFACE_CAPABILITY_ICMPV4_RX_CHECKSUM ) + // NX_INTERFACE_CAPABILITY_ICMPV6_TX_CHECKSUM | \ + // NX_INTERFACE_CAPABILITY_ICMPV6_RX_CHECKSUM ) +*/ + +/****** DRIVER SPECIFIC ****** Start of part/vendor specific constants area. Include any such constants here! */ + +/* Enable checksum offload. */ +#define IMX_CHECKSUM_OFFLOAD + +#define PHY_ADDRESS 1 +#define PHY_ICS 0x1B +#define PHY_ICS_LINKUPIE 0x0100 +#define PHY_ICS_LINKUPI 0x0001 +#define PHY_ICS_LINKDOWNIE 0x0400 +#define PHY_ICS_LINKDOWNI 0x0004 + +/* Define the number of descriptors and attached packets for transmit and receive operations. */ + +#ifndef NX_DRIVER_TX_DESCRIPTORS +#define NX_DRIVER_TX_DESCRIPTORS 64 +#endif + +#ifndef NX_DRIVER_RX_DESCRIPTORS +#define NX_DRIVER_RX_DESCRIPTORS 8 +#endif + + +/****** DRIVER SPECIFIC ****** End of part/vendor specific constant area! */ + + +/* Define basic Ethernet driver information typedef. Note that this typedefs is designed to be used only + in the driver's C file. */ + +typedef struct NX_DRIVER_INFORMATION_STRUCT +{ + /* NetX IP instance that this driver is attached to. */ + NX_IP *nx_driver_information_ip_ptr; + + /* Driver's current state. */ + ULONG nx_driver_information_state ; + + /* Packet pool used for receiving packets. */ + NX_PACKET_POOL *nx_driver_information_packet_pool_ptr; + + /* Define the driver interface association. */ + NX_INTERFACE *nx_driver_information_interface; + + /* Define the deferred event field. This will contain bits representing events + deferred from the ISR for processing in the thread context. */ + ULONG nx_driver_information_deferred_events; + + + /****** DRIVER SPECIFIC ****** Start of part/vendor specific driver information area. Include any such constants here! */ + + /* Indices to current receive/transmit descriptors. */ + UINT nx_driver_information_receive_current_index; + UINT nx_driver_information_transmit_current_index; + + /* Transmit release index. */ + UINT nx_driver_information_transmit_release_index; + + /* Define the number of transmit buffers in use. */ + UINT nx_driver_information_number_of_transmit_buffers_in_use; + + /* Define the Ethernet RX & TX DMA Descriptors. */ + UCHAR nx_driver_information_dma_rx_descriptors_area[sizeof(enet_rx_bd_struct_t) * NX_DRIVER_RX_DESCRIPTORS + 16]; + UCHAR nx_driver_information_dma_tx_descriptors_area[sizeof(enet_tx_bd_struct_t) * NX_DRIVER_TX_DESCRIPTORS + 16]; + + enet_rx_bd_struct_t *nx_driver_information_dma_rx_descriptors; + enet_tx_bd_struct_t *nx_driver_information_dma_tx_descriptors; + + /* Define the association between buffer descriptors and NetX packets. */ + NX_PACKET *nx_driver_information_transmit_packets[NX_DRIVER_TX_DESCRIPTORS]; + NX_PACKET *nx_driver_information_receive_packets[NX_DRIVER_RX_DESCRIPTORS]; + + /* Define the size of a rx buffer size. */ + ULONG nx_driver_information_rx_buffer_size; + + UCHAR nx_driver_information_multicast_count[64]; + + UINT nx_driver_information_link_speed; + UINT nx_driver_information_link_duplex; + + +#ifdef NX_DIRVER_INTERNAL_TRANSMIT_QUEUE + + /* Define the parameters in the internal driver transmit queue. The queue is maintained as a singularly + linked-list with head and tail pointers. The maximum number of packets on the queue is regulated by + the constant NX_DRIVER_MAX_TRANSMIT_QUEUE_DEPTH, which is defined above. When this number is reached, + the oldest packet is discarded after the new packet is queued. */ + ULONG nx_driver_transmit_packets_queued; + NX_PACKET nx_driver_transmit_queue_head; + NX_PACKET nx_driver_transmit_queue_tail; +#endif + + + /****** DRIVER SPECIFIC ****** End of part/vendor specific driver information area. */ + +} NX_DRIVER_INFORMATION; + +#endif + + +/****** DRIVER SPECIFIC ****** Start of part/vendor specific external function prototypes. A typical NetX Ethernet driver + should expose its entry function as well as its interrupt handling function(s) here. All other + functions in the driver should have local scope, i.e., defined as static. */ + +/* Define global driver entry function. */ + +VOID nx_driver_imx(NX_IP_DRIVER *driver_req_ptr); + +/* Define global driver interrupt dispatch function. */ + + +/****** DRIVER SPECIFIC ****** End of part/vendor specific external function prototypes. */ + + +#ifdef __cplusplus +/* Yes, C++ compiler is present. Use standard C. */ + } +#endif + +#endif diff --git a/NXP/MIMXRT1064-EVK/lib/netxduo/nx_user.h b/targets/NXP/MIMXRT1064-EVK/lib/netxduo/nx_user.h similarity index 100% rename from NXP/MIMXRT1064-EVK/lib/netxduo/nx_user.h rename to targets/NXP/MIMXRT1064-EVK/lib/netxduo/nx_user.h diff --git a/targets/NXP/MIMXRT1064-EVK/lib/phyksz8081/fsl_phy.c b/targets/NXP/MIMXRT1064-EVK/lib/phyksz8081/fsl_phy.c new file mode 100644 index 00000000..af520c4d --- /dev/null +++ b/targets/NXP/MIMXRT1064-EVK/lib/phyksz8081/fsl_phy.c @@ -0,0 +1,301 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * Copyright 2016-2020 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "fsl_phy.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @brief Defines the timeout macro. */ +#define PHY_TIMEOUT_COUNT 100000U + +/******************************************************************************* + * Prototypes + ******************************************************************************/ + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/******************************************************************************* + * Code + ******************************************************************************/ + +status_t PHY_Init(ENET_Type *base, uint32_t phyAddr, uint32_t srcClock_Hz) +{ + uint32_t bssReg; + uint32_t counter = PHY_TIMEOUT_COUNT; + uint32_t idReg = 0; + status_t result = kStatus_Success; + uint32_t instance = ENET_GetInstance(base); + uint32_t timeDelay; + uint32_t ctlReg = 0; + +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + /* Set SMI first. */ + CLOCK_EnableClock(s_enetClock[instance]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ + ENET_SetSMI(base, srcClock_Hz, false); + + /* Initialization after PHY stars to work. */ + while ((idReg != PHY_CONTROL_ID1) && (counter != 0U)) + { + (void)PHY_Read(base, phyAddr, PHY_ID1_REG, &idReg); + counter--; + } + + if (counter == 0U) + { + return kStatus_Fail; + } + + /* Reset PHY. */ + counter = PHY_TIMEOUT_COUNT; + result = PHY_Write(base, phyAddr, PHY_BASICCONTROL_REG, PHY_BCTL_RESET_MASK); + if (result == kStatus_Success) + { +#if defined(FSL_FEATURE_PHYKSZ8081_USE_RMII50M_MODE) + uint32_t data = 0; + result = PHY_Read(base, phyAddr, PHY_CONTROL2_REG, &data); + if (result != kStatus_Success) + { + return result; + } + result = PHY_Write(base, phyAddr, PHY_CONTROL2_REG, (data | PHY_CTL2_REFCLK_SELECT_MASK)); + if (result != kStatus_Success) + { + return result; + } +#endif /* FSL_FEATURE_PHYKSZ8081_USE_RMII50M_MODE */ + + /* Set the negotiation. */ + result = PHY_Write(base, phyAddr, PHY_AUTONEG_ADVERTISE_REG, + (PHY_100BASETX_FULLDUPLEX_MASK | PHY_100BASETX_HALFDUPLEX_MASK | + PHY_10BASETX_FULLDUPLEX_MASK | PHY_10BASETX_HALFDUPLEX_MASK | 0x1U)); + if (result == kStatus_Success) + { + result = + PHY_Write(base, phyAddr, PHY_BASICCONTROL_REG, (PHY_BCTL_AUTONEG_MASK | PHY_BCTL_RESTART_AUTONEG_MASK)); + if (result == kStatus_Success) + { + /* Check auto negotiation complete. */ + while (counter-- != 0U) + { + result = PHY_Read(base, phyAddr, PHY_BASICSTATUS_REG, &bssReg); + if (result == kStatus_Success) + { + (void)PHY_Read(base, phyAddr, PHY_CONTROL1_REG, &ctlReg); + if (((bssReg & PHY_BSTATUS_AUTONEGCOMP_MASK) != 0U) && ((ctlReg & PHY_LINK_READY_MASK) != 0U)) + { + /* Wait a moment for Phy status stable. */ + for (timeDelay = 0; timeDelay < PHY_TIMEOUT_COUNT; timeDelay++) + { + __ASM("nop"); + } + break; + } + } + + if (counter == 0U) + { + return kStatus_PHY_AutoNegotiateFail; + } + } + } + } + } + + return result; +} + +status_t PHY_Write(ENET_Type *base, uint32_t phyAddr, uint32_t phyReg, uint32_t data) +{ + uint32_t counter; + + /* Clear the SMI interrupt event. */ + ENET_ClearInterruptStatus(base, ENET_EIR_MII_MASK); + + /* Starts a SMI write command. */ + ENET_StartSMIWrite(base, phyAddr, phyReg, kENET_MiiWriteValidFrame, data); + + /* Wait for SMI complete. */ + for (counter = PHY_TIMEOUT_COUNT; counter > 0U; counter--) + { + if ((ENET_GetInterruptStatus(base) & ENET_EIR_MII_MASK) != 0U) + { + break; + } + } + + /* Check for timeout. */ + if (counter == 0U) + { + return kStatus_PHY_SMIVisitTimeout; + } + + /* Clear MII interrupt event. */ + ENET_ClearInterruptStatus(base, ENET_EIR_MII_MASK); + + return kStatus_Success; +} + +status_t PHY_Read(ENET_Type *base, uint32_t phyAddr, uint32_t phyReg, uint32_t *dataPtr) +{ + assert(dataPtr); + + uint32_t counter; + + /* Clear the MII interrupt event. */ + ENET_ClearInterruptStatus(base, ENET_EIR_MII_MASK); + + /* Starts a SMI read command operation. */ + ENET_StartSMIRead(base, phyAddr, phyReg, kENET_MiiReadValidFrame); + + /* Wait for MII complete. */ + for (counter = PHY_TIMEOUT_COUNT; counter > 0U; counter--) + { + if ((ENET_GetInterruptStatus(base) & ENET_EIR_MII_MASK) != 0U) + { + break; + } + } + + /* Check for timeout. */ + if (counter == 0U) + { + return kStatus_PHY_SMIVisitTimeout; + } + + /* Get data from MII register. */ + *dataPtr = ENET_ReadSMIData(base); + + /* Clear MII interrupt event. */ + ENET_ClearInterruptStatus(base, ENET_EIR_MII_MASK); + + return kStatus_Success; +} + +status_t PHY_EnableLoopback(ENET_Type *base, uint32_t phyAddr, phy_loop_t mode, phy_speed_t speed, bool enable) +{ + status_t result; + uint32_t data = 0; + + /* Set the loop mode. */ + if (enable) + { + if (mode == kPHY_LocalLoop) + { + if (speed == kPHY_Speed100M) + { + data = PHY_BCTL_SPEED_100M_MASK | PHY_BCTL_DUPLEX_MASK | PHY_BCTL_LOOP_MASK; + } + else + { + data = PHY_BCTL_DUPLEX_MASK | PHY_BCTL_LOOP_MASK; + } + return PHY_Write(base, phyAddr, PHY_BASICCONTROL_REG, data); + } + else + { + /* First read the current status in control register. */ + result = PHY_Read(base, phyAddr, PHY_CONTROL2_REG, &data); + if (result == kStatus_Success) + { + return PHY_Write(base, phyAddr, PHY_CONTROL2_REG, (data | PHY_CTL2_REMOTELOOP_MASK)); + } + } + } + else + { + /* Disable the loop mode. */ + if (mode == kPHY_LocalLoop) + { + /* First read the current status in control register. */ + result = PHY_Read(base, phyAddr, PHY_BASICCONTROL_REG, &data); + if (result == kStatus_Success) + { + data &= ~PHY_BCTL_LOOP_MASK; + return PHY_Write(base, phyAddr, PHY_BASICCONTROL_REG, (data | PHY_BCTL_RESTART_AUTONEG_MASK)); + } + } + else + { + /* First read the current status in control one register. */ + result = PHY_Read(base, phyAddr, PHY_CONTROL2_REG, &data); + if (result == kStatus_Success) + { + return PHY_Write(base, phyAddr, PHY_CONTROL2_REG, (data & ~PHY_CTL2_REMOTELOOP_MASK)); + } + } + } + return result; +} + +status_t PHY_GetLinkStatus(ENET_Type *base, uint32_t phyAddr, bool *status) +{ + assert(status); + + status_t result = kStatus_Success; + uint32_t data; + + /* Read the basic status register. */ + result = PHY_Read(base, phyAddr, PHY_BASICSTATUS_REG, &data); + if (result == kStatus_Success) + { + if ((PHY_BSTATUS_LINKSTATUS_MASK & data) == 0U) + { + /* link down. */ + *status = false; + } + else + { + /* link up. */ + *status = true; + } + } + return result; +} + +status_t PHY_GetLinkSpeedDuplex(ENET_Type *base, uint32_t phyAddr, phy_speed_t *speed, phy_duplex_t *duplex) +{ + assert(duplex); + + status_t result = kStatus_Success; + uint32_t data, ctlReg; + + /* Read the control two register. */ + result = PHY_Read(base, phyAddr, PHY_CONTROL1_REG, &ctlReg); + if (result == kStatus_Success) + { + data = ctlReg & PHY_CTL1_SPEEDUPLX_MASK; + if ((PHY_CTL1_10FULLDUPLEX_MASK == data) || (PHY_CTL1_100FULLDUPLEX_MASK == data)) + { + /* Full duplex. */ + *duplex = kPHY_FullDuplex; + } + else + { + /* Half duplex. */ + *duplex = kPHY_HalfDuplex; + } + + data = ctlReg & PHY_CTL1_SPEEDUPLX_MASK; + if ((PHY_CTL1_100HALFDUPLEX_MASK == data) || (PHY_CTL1_100FULLDUPLEX_MASK == data)) + { + /* 100M speed. */ + *speed = kPHY_Speed100M; + } + else + { /* 10M speed. */ + *speed = kPHY_Speed10M; + } + } + + return result; +} diff --git a/targets/NXP/MIMXRT1064-EVK/lib/phyksz8081/fsl_phy.h b/targets/NXP/MIMXRT1064-EVK/lib/phyksz8081/fsl_phy.h new file mode 100644 index 00000000..692457d4 --- /dev/null +++ b/targets/NXP/MIMXRT1064-EVK/lib/phyksz8081/fsl_phy.h @@ -0,0 +1,200 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * Copyright 2016-2020 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +#ifndef _FSL_PHY_H_ +#define _FSL_PHY_H_ + +#include "fsl_enet.h" + +/*! + * @addtogroup phy_driver + * @{ + */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @brief PHY driver version */ +#define FSL_PHY_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) /*!< Version 2.0.0. */ + +/*! @brief Defines the PHY registers. */ +#define PHY_BASICCONTROL_REG 0x00U /*!< The PHY basic control register. */ +#define PHY_BASICSTATUS_REG 0x01U /*!< The PHY basic status register. */ +#define PHY_ID1_REG 0x02U /*!< The PHY ID one register. */ +#define PHY_ID2_REG 0x03U /*!< The PHY ID two register. */ +#define PHY_AUTONEG_ADVERTISE_REG 0x04U /*!< The PHY auto-negotiate advertise register. */ +#define PHY_CONTROL1_REG 0x1EU /*!< The PHY control one register. */ +#define PHY_CONTROL2_REG 0x1FU /*!< The PHY control two register. */ + +#define PHY_CONTROL_ID1 0x22U /*!< The PHY ID1*/ + +/*! @brief Defines the mask flag in basic control register. */ +#define PHY_BCTL_DUPLEX_MASK 0x0100U /*!< The PHY duplex bit mask. */ +#define PHY_BCTL_RESTART_AUTONEG_MASK 0x0200U /*!< The PHY restart auto negotiation mask. */ +#define PHY_BCTL_AUTONEG_MASK 0x1000U /*!< The PHY auto negotiation bit mask. */ +#define PHY_BCTL_SPEED_MASK 0x2000U /*!< The PHY speed bit mask. */ +#define PHY_BCTL_LOOP_MASK 0x4000U /*!< The PHY loop bit mask. */ +#define PHY_BCTL_RESET_MASK 0x8000U /*!< The PHY reset bit mask. */ +#define PHY_BCTL_SPEED_100M_MASK 0x2000U /*!< The PHY 100M speed mask. */ + +/*!@brief Defines the mask flag of operation mode in control two register*/ +#define PHY_CTL2_REMOTELOOP_MASK 0x0004U /*!< The PHY remote loopback mask. */ +#define PHY_CTL2_REFCLK_SELECT_MASK 0x0080U /*!< The PHY RMII reference clock select. */ +#define PHY_CTL1_10HALFDUPLEX_MASK 0x0001U /*!< The PHY 10M half duplex mask. */ +#define PHY_CTL1_100HALFDUPLEX_MASK 0x0002U /*!< The PHY 100M half duplex mask. */ +#define PHY_CTL1_10FULLDUPLEX_MASK 0x0005U /*!< The PHY 10M full duplex mask. */ +#define PHY_CTL1_100FULLDUPLEX_MASK 0x0006U /*!< The PHY 100M full duplex mask. */ +#define PHY_CTL1_SPEEDUPLX_MASK 0x0007U /*!< The PHY speed and duplex mask. */ +#define PHY_CTL1_ENERGYDETECT_MASK 0x10U /*!< The PHY signal present on rx differential pair. */ +#define PHY_CTL1_LINKUP_MASK 0x100U /*!< The PHY link up. */ +#define PHY_LINK_READY_MASK (PHY_CTL1_ENERGYDETECT_MASK | PHY_CTL1_LINKUP_MASK) + +/*! @brief Defines the mask flag in basic status register. */ +#define PHY_BSTATUS_LINKSTATUS_MASK 0x0004U /*!< The PHY link status mask. */ +#define PHY_BSTATUS_AUTONEGABLE_MASK 0x0008U /*!< The PHY auto-negotiation ability mask. */ +#define PHY_BSTATUS_AUTONEGCOMP_MASK 0x0020U /*!< The PHY auto-negotiation complete mask. */ + +/*! @brief Defines the mask flag in PHY auto-negotiation advertise register. */ +#define PHY_100BaseT4_ABILITY_MASK 0x200U /*!< The PHY have the T4 ability. */ +#define PHY_100BASETX_FULLDUPLEX_MASK 0x100U /*!< The PHY has the 100M full duplex ability.*/ +#define PHY_100BASETX_HALFDUPLEX_MASK 0x080U /*!< The PHY has the 100M full duplex ability.*/ +#define PHY_10BASETX_FULLDUPLEX_MASK 0x040U /*!< The PHY has the 10M full duplex ability.*/ +#define PHY_10BASETX_HALFDUPLEX_MASK 0x020U /*!< The PHY has the 10M full duplex ability.*/ + +/*! @brief Defines the PHY status. */ +enum +{ + kStatus_PHY_SMIVisitTimeout = MAKE_STATUS(kStatusGroup_PHY, 1), /*!< ENET PHY SMI visit timeout. */ + kStatus_PHY_AutoNegotiateFail = MAKE_STATUS(kStatusGroup_PHY, 2) /*!< ENET PHY AutoNegotiate Fail. */ +}; + +/*! @brief Defines the PHY link speed. This is align with the speed for ENET MAC. */ +typedef enum _phy_speed +{ + kPHY_Speed10M = 0U, /*!< ENET PHY 10M speed. */ + kPHY_Speed100M /*!< ENET PHY 100M speed. */ +} phy_speed_t; + +/*! @brief Defines the PHY link duplex. */ +typedef enum _phy_duplex +{ + kPHY_HalfDuplex = 0U, /*!< ENET PHY half duplex. */ + kPHY_FullDuplex /*!< ENET PHY full duplex. */ +} phy_duplex_t; + +/*! @brief Defines the PHY loopback mode. */ +typedef enum _phy_loop +{ + kPHY_LocalLoop = 0U, /*!< ENET PHY local loopback. */ + kPHY_RemoteLoop /*!< ENET PHY remote loopback. */ +} phy_loop_t; + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @name PHY Driver + * @{ + */ + +/*! + * @brief Initializes PHY. + * + * This function initialize the SMI interface and initialize PHY. + * The SMI is the MII management interface between PHY and MAC, which should be + * firstly initialized before any other operation for PHY. The PHY initialize with auto-negotiation. + * + * @param base ENET peripheral base address. + * @param phyAddr The PHY address. + * @param srcClock_Hz The module clock frequency - system clock for MII management interface - SMI. + * @retval kStatus_Success PHY initialize success + * @retval kStatus_PHY_SMIVisitTimeout PHY SMI visit time out + * @retval kStatus_PHY_AutoNegotiateFail PHY auto negotiate fail + */ +status_t PHY_Init(ENET_Type *base, uint32_t phyAddr, uint32_t srcClock_Hz); + +/*! + * @brief PHY Write function. This function write data over the SMI to + * the specified PHY register. This function is called by all PHY interfaces. + * + * @param base ENET peripheral base address. + * @param phyAddr The PHY address. + * @param phyReg The PHY register. + * @param data The data written to the PHY register. + * @retval kStatus_Success PHY write success + * @retval kStatus_PHY_SMIVisitTimeout PHY SMI visit time out + */ +status_t PHY_Write(ENET_Type *base, uint32_t phyAddr, uint32_t phyReg, uint32_t data); + +/*! + * @brief PHY Read function. This interface read data over the SMI from the + * specified PHY register. This function is called by all PHY interfaces. + * + * @param base ENET peripheral base address. + * @param phyAddr The PHY address. + * @param phyReg The PHY register. + * @param dataPtr The address to store the data read from the PHY register. + * @retval kStatus_Success PHY read success + * @retval kStatus_PHY_SMIVisitTimeout PHY SMI visit time out + */ +status_t PHY_Read(ENET_Type *base, uint32_t phyAddr, uint32_t phyReg, uint32_t *dataPtr); + +/*! + * @brief Enables/disables PHY loopback. + * + * @param base ENET peripheral base address. + * @param phyAddr The PHY address. + * @param mode The loopback mode to be enabled, please see "phy_loop_t". + * the two loopback mode should not be both set. when one loopback mode is set + * the other one should be disabled. + * @param speed PHY speed for loopback mode. + * @param enable True to enable, false to disable. + * @retval kStatus_Success PHY loopback success + * @retval kStatus_PHY_SMIVisitTimeout PHY SMI visit time out + */ +status_t PHY_EnableLoopback(ENET_Type *base, uint32_t phyAddr, phy_loop_t mode, phy_speed_t speed, bool enable); + +/*! + * @brief Gets the PHY link status. + * + * @param base ENET peripheral base address. + * @param phyAddr The PHY address. + * @param status The link up or down status of the PHY. + * - true the link is up. + * - false the link is down. + * @retval kStatus_Success PHY get link status success + * @retval kStatus_PHY_SMIVisitTimeout PHY SMI visit time out + */ +status_t PHY_GetLinkStatus(ENET_Type *base, uint32_t phyAddr, bool *status); + +/*! + * @brief Gets the PHY link speed and duplex. + * + * @param base ENET peripheral base address. + * @param phyAddr The PHY address. + * @param speed The address of PHY link speed. + * @param duplex The link duplex of PHY. + * @retval kStatus_Success PHY get link speed and duplex success + * @retval kStatus_PHY_SMIVisitTimeout PHY SMI visit time out + */ +status_t PHY_GetLinkSpeedDuplex(ENET_Type *base, uint32_t phyAddr, phy_speed_t *speed, phy_duplex_t *duplex); + +/* @} */ + +#if defined(__cplusplus) +} +#endif + +/*! @}*/ + +#endif /* _FSL_PHY_H_ */ diff --git a/NXP/MIMXRT1064-EVK/lib/threadx/tx_user.h b/targets/NXP/MIMXRT1064-EVK/lib/threadx/tx_user.h similarity index 94% rename from NXP/MIMXRT1064-EVK/lib/threadx/tx_user.h rename to targets/NXP/MIMXRT1064-EVK/lib/threadx/tx_user.h index b6f7d03c..3deb0a1e 100644 --- a/NXP/MIMXRT1064-EVK/lib/threadx/tx_user.h +++ b/targets/NXP/MIMXRT1064-EVK/lib/threadx/tx_user.h @@ -23,4 +23,7 @@ #define TX_TIMER_TICKS_PER_SECOND 100 #endif +/* Enable ThreadX runtime stack checking */ +#define TX_ENABLE_STACK_CHECKING + #endif /* TX_USER_H */ diff --git a/NXP/MIMXRT1064-EVK/renode/mimxrt1064-evk.repl b/targets/NXP/MIMXRT1064-EVK/renode/mimxrt1064-evk.repl similarity index 100% rename from NXP/MIMXRT1064-EVK/renode/mimxrt1064-evk.repl rename to targets/NXP/MIMXRT1064-EVK/renode/mimxrt1064-evk.repl diff --git a/NXP/MIMXRT1064-EVK/renode/mimxrt1064-evk.resc b/targets/NXP/MIMXRT1064-EVK/renode/mimxrt1064-evk.resc similarity index 95% rename from NXP/MIMXRT1064-EVK/renode/mimxrt1064-evk.resc rename to targets/NXP/MIMXRT1064-EVK/renode/mimxrt1064-evk.resc index ed38157e..acab50dc 100644 --- a/NXP/MIMXRT1064-EVK/renode/mimxrt1064-evk.resc +++ b/targets/NXP/MIMXRT1064-EVK/renode/mimxrt1064-evk.resc @@ -17,7 +17,7 @@ mach create "mimxrt1064-evk" $platform?=$ORIGIN/mimxrt1064-evk.repl machine LoadPlatformDescription $platform -$bin?=$ORIGIN/../build/mimxrt1064_threadx.elf +$bin?=$ORIGIN/../build/app/demos/netx_echo/mimxrt1064_threadx.elf # Create Ethernet Switch and connect ENET peripheral emulation CreateSwitch "switch" diff --git a/NXP/MIMXRT1064-EVK/renode/mimxrt1064-headless-multinode.resc b/targets/NXP/MIMXRT1064-EVK/renode/mimxrt1064-headless-multinode.resc similarity index 100% rename from NXP/MIMXRT1064-EVK/renode/mimxrt1064-headless-multinode.resc rename to targets/NXP/MIMXRT1064-EVK/renode/mimxrt1064-headless-multinode.resc diff --git a/NXP/MIMXRT1064-EVK/renode/mimxrt1064-headless-single.resc b/targets/NXP/MIMXRT1064-EVK/renode/mimxrt1064-headless-single.resc similarity index 100% rename from NXP/MIMXRT1064-EVK/renode/mimxrt1064-headless-single.resc rename to targets/NXP/MIMXRT1064-EVK/renode/mimxrt1064-headless-single.resc diff --git a/NXP/MIMXRT1064-EVK/renode/mimxrt1064-network-multinode.resc b/targets/NXP/MIMXRT1064-EVK/renode/mimxrt1064-network-multinode.resc similarity index 100% rename from NXP/MIMXRT1064-EVK/renode/mimxrt1064-network-multinode.resc rename to targets/NXP/MIMXRT1064-EVK/renode/mimxrt1064-network-multinode.resc diff --git a/NXP/MIMXRT1064-EVK/renode/mimxrt1064-trng-console.resc b/targets/NXP/MIMXRT1064-EVK/renode/mimxrt1064-trng-console.resc similarity index 100% rename from NXP/MIMXRT1064-EVK/renode/mimxrt1064-trng-console.resc rename to targets/NXP/MIMXRT1064-EVK/renode/mimxrt1064-trng-console.resc diff --git a/NXP/MIMXRT1064-EVK/scripts/build.ps1 b/targets/NXP/MIMXRT1064-EVK/scripts/build.ps1 similarity index 100% rename from NXP/MIMXRT1064-EVK/scripts/build.ps1 rename to targets/NXP/MIMXRT1064-EVK/scripts/build.ps1 diff --git a/NXP/MIMXRT1064-EVK/scripts/build.sh b/targets/NXP/MIMXRT1064-EVK/scripts/build.sh similarity index 100% rename from NXP/MIMXRT1064-EVK/scripts/build.sh rename to targets/NXP/MIMXRT1064-EVK/scripts/build.sh diff --git a/NXP/MIMXRT1064-EVK/scripts/fetch_sdk.ps1 b/targets/NXP/MIMXRT1064-EVK/scripts/fetch_sdk.ps1 similarity index 54% rename from NXP/MIMXRT1064-EVK/scripts/fetch_sdk.ps1 rename to targets/NXP/MIMXRT1064-EVK/scripts/fetch_sdk.ps1 index b99f9637..a52ac4f8 100644 --- a/NXP/MIMXRT1064-EVK/scripts/fetch_sdk.ps1 +++ b/targets/NXP/MIMXRT1064-EVK/scripts/fetch_sdk.ps1 @@ -9,6 +9,7 @@ # Contributors: # Ali Eissa - 2026 version. +$ErrorActionPreference = "Stop" $BoardDir = Resolve-Path "$PSScriptRoot/.." $LibDir = Join-Path $BoardDir "lib/mcux-sdk" $DeviceDir = Join-Path $LibDir "devices/MIMXRT1064" @@ -45,15 +46,33 @@ function Clean-Temp { } } +function Verify-Sha256 { + param( + [string]$FilePath, + [string]$ExpectedHash + ) + $actualHash = (Get-FileHash -Path $FilePath -Algorithm SHA256).Hash.ToLower() + if ($actualHash -ne $ExpectedHash.ToLower()) { + throw "SHA256 checksum mismatch for $FilePath! Expected: $ExpectedHash, Got: $actualHash" + } +} + try { - # 1. Download official NXP MIMXRT1064 DFP pack from NXP repository + # 1. Download official NXP MIMXRT1064 DFP pack from NXP repository (pinned v15.1.0) $packUrl = "https://mcuxpresso.nxp.com/cmsis_pack/repo/NXP.MIMXRT1064_DFP.15.1.0.pack" + $packSha256 = "14e02f0108beba1cfe9de6b2be7b1f874695614dcc16126c452bde1b68b509f6" $packZip = Join-Path $TempDir "dfp.zip" $packExtract = Join-Path $TempDir "dfp_extracted" - Write-Host "[INFO] Downloading official NXP MIMXRT1064 Device Pack..." + Write-Host "[INFO] Downloading official NXP MIMXRT1064 Device Pack (v15.1.0)..." [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 - Invoke-WebRequest -Uri $packUrl -OutFile $packZip -UseBasicParsing + if (Get-Command curl.exe -ErrorAction SilentlyContinue) { + & curl.exe --retry 3 --retry-delay 2 -fsSL $packUrl -o $packZip + } else { + Invoke-WebRequest -Uri $packUrl -OutFile $packZip -UseBasicParsing + } + Verify-Sha256 -FilePath $packZip -ExpectedHash $packSha256 + Write-Host "[OK] NXP Device Pack verified (SHA256: $packSha256)" Write-Host "[INFO] Extracting Device Pack..." Expand-Archive -Path $packZip -DestinationPath $packExtract -Force @@ -68,9 +87,7 @@ try { ) foreach ($file in $deviceFiles) { $source = Join-Path $packExtract $file - if (Test-Path $source) { - Copy-Item -Path $source -Destination $DeviceDir -Force - } + Copy-Item -Path $source -Destination $DeviceDir -Force } # Copy core peripheral drivers @@ -85,9 +102,7 @@ try { ) foreach ($file in $driverList) { $source = Join-Path $packExtract "drivers/$file" - if (Test-Path $source) { - Copy-Item -Path $source -Destination $DriversDir -Force - } + Copy-Item -Path $source -Destination $DriversDir -Force } # Copy utilities (debug console & string formatting) @@ -101,9 +116,7 @@ try { ) foreach ($file in $utilFiles) { $source = Join-Path $packExtract $file - if (Test-Path $source) { - Copy-Item -Path $source -Destination $UtilitiesDir -Force - } + Copy-Item -Path $source -Destination $UtilitiesDir -Force } # Copy UART component adapter @@ -114,31 +127,38 @@ try { ) foreach ($file in $compUartFiles) { $source = Join-Path $packExtract $file - if (Test-Path $source) { - Copy-Item -Path $source -Destination $compUartDest -Force - } + Copy-Item -Path $source -Destination $compUartDest -Force } # Copy XIP flexspi boot header from pack $xipSource = Join-Path $packExtract "xip" - if (Test-Path $xipSource) { - Copy-Item -Path "$xipSource/*" -Destination $DeviceDir -Recurse -Force - } + Copy-Item -Path "$xipSource/*" -Destination $DeviceDir -Recurse -Force Write-Host "[OK] NXP Device, Driver, Utility, and Component files copied" Write-Host "" - # Helper function to download with retries for GitHub CDN resilience + # Helper function to download with retries and SHA256 checksum verification function Download-WithRetry { - param([string]$Uri, [string]$OutFile, [int]$MaxAttempts = 4) + param( + [string]$Uri, + [string]$OutFile, + [string]$ExpectedHash = "", + [int]$MaxAttempts = 4 + ) for ($i = 1; $i -le $MaxAttempts; $i++) { try { if (Get-Command curl.exe -ErrorAction SilentlyContinue) { & curl.exe --retry 3 --retry-delay 2 -fsSL $Uri -o $OutFile if ($LASTEXITCODE -eq 0 -and (Test-Path $OutFile) -and ((Get-Item $OutFile).Length -gt 0)) { + if ($ExpectedHash) { + Verify-Sha256 -FilePath $OutFile -ExpectedHash $ExpectedHash + } return } } Invoke-WebRequest -Uri $Uri -OutFile $OutFile -UseBasicParsing -TimeoutSec 30 + if ($ExpectedHash) { + Verify-Sha256 -FilePath $OutFile -ExpectedHash $ExpectedHash + } return } catch { @@ -148,76 +168,59 @@ try { } } - # 2. Download EVK-MIMXRT1064 Board Initialization Files from official NXP mcuxsdk-examples - $rawBase = "https://raw.githubusercontent.com/nxp-mcuxpresso/mcuxsdk-examples/main/_boards/evkmimxrt1064" + # 2. Download EVK-MIMXRT1064 Board Support Files (pinned to commit 2a340e10 from nxp-mcuxpresso/mcuxsdk-examples) + $mcuxExamplesCommit = "2a340e10a1105bc0af8e7176bc19148911f4cf12" + $rawBase = "https://raw.githubusercontent.com/nxp-mcuxpresso/mcuxsdk-examples/$mcuxExamplesCommit/_boards/evkmimxrt1064" $boardFiles = @( - @{ Remote = "$rawBase/board.c"; Local = "board.c" }, - @{ Remote = "$rawBase/board.h"; Local = "board.h" }, - @{ Remote = "$rawBase/project_template/clock_config.c"; Local = "clock_config.c" }, - @{ Remote = "$rawBase/project_template/clock_config.h"; Local = "clock_config.h" }, - @{ Remote = "$rawBase/project_template/pin_mux.c"; Local = "pin_mux.c" }, - @{ Remote = "$rawBase/project_template/pin_mux.h"; Local = "pin_mux.h" }, - @{ Remote = "$rawBase/dcd.c"; Local = "dcd.c" }, - @{ Remote = "$rawBase/dcd.h"; Local = "dcd.h" }, - @{ Remote = "$rawBase/xip/evkmimxrt1064_flexspi_nor_config.c"; Local = "evkmimxrt1064_flexspi_nor_config.c" }, - @{ Remote = "$rawBase/xip/evkmimxrt1064_flexspi_nor_config.h"; Local = "evkmimxrt1064_flexspi_nor_config.h" } + @{ Remote = "$rawBase/board.c"; Local = "board.c"; Hash = "f28885b9ac349a06a6b38f0376f6872a25ec131ab7d37947a0576255579cd959" }, + @{ Remote = "$rawBase/board.h"; Local = "board.h"; Hash = "9c25debd61b7fc153eeedd569155dfc8f9d1349192c6de2b431742ee6f9bb17e" }, + @{ Remote = "$rawBase/project_template/clock_config.c"; Local = "clock_config.c"; Hash = "ca20b253229ef02e74a9d0041173c5e1fc0c5c3df048a53be8b44e1e4218ef03" }, + @{ Remote = "$rawBase/project_template/clock_config.h"; Local = "clock_config.h"; Hash = "52036470ef08b16daf7ed1382a8c3c0bcc123336afc2b07df807e793365b3e80" }, + @{ Remote = "$rawBase/project_template/pin_mux.c"; Local = "pin_mux.c"; Hash = "4bf784e2685555e6297adccb78a27de5754e5320911bc503b5ab563577599c39" }, + @{ Remote = "$rawBase/project_template/pin_mux.h"; Local = "pin_mux.h"; Hash = "f696267090a271e12d9c9f3ccb0e2dfb721025ddd3728b32ab33a9fb79acbc70" }, + @{ Remote = "$rawBase/dcd.c"; Local = "dcd.c"; Hash = "798cd3fffea9b3b1917d6750d40735b6bc890e770f8d8b9167238220b0fae21f" }, + @{ Remote = "$rawBase/dcd.h"; Local = "dcd.h"; Hash = "3a5268f0ccdc02aa6df55b3fca87171df35161cca0c3e15971ac082cdefde7a3" }, + @{ Remote = "$rawBase/xip/evkmimxrt1064_flexspi_nor_config.c"; Local = "evkmimxrt1064_flexspi_nor_config.c"; Hash = "f6fa3d1e3a09c1a4a9d3fc44aed23513e12341e6db96aa3427c923e6b41c6e46" }, + @{ Remote = "$rawBase/xip/evkmimxrt1064_flexspi_nor_config.h"; Local = "evkmimxrt1064_flexspi_nor_config.h"; Hash = "4073f8c6e09fccc879dcedb6fe79f679bc8c9840bb90a7f527279a9a021813d3" } ) - Write-Host "[INFO] Downloading EVK-MIMXRT1064 board support files..." + Write-Host "[INFO] Downloading EVK-MIMXRT1064 board support files (pinned: $($mcuxExamplesCommit.Substring(0,8)))..." foreach ($item in $boardFiles) { $dest = Join-Path $BoardFilesDir $item.Local - Download-WithRetry -Uri $item.Remote -OutFile $dest + Download-WithRetry -Uri $item.Remote -OutFile $dest -ExpectedHash $item.Hash } - # Copy official GNU GCC Linker Script & Startup File from DFP pack into board directory - Write-Host "[INFO] Copying official NXP GNU GCC Linker Script and Startup File into board directory..." - $gccSource = Join-Path $packExtract "gcc" - if (Test-Path $gccSource) { - if (Test-Path "$gccSource/MIMXRT1064xxxxx_flexspi_nor.ld") { - Copy-Item -Path "$gccSource/MIMXRT1064xxxxx_flexspi_nor.ld" -Destination $BoardFilesDir -Force - } - if (Test-Path "$gccSource/startup_MIMXRT1064.S") { - Copy-Item -Path "$gccSource/startup_MIMXRT1064.S" -Destination $BoardFilesDir -Force - } - } - Write-Host "[OK] Board support and official GCC reference files copied" + Write-Host "[OK] Board support files verified & downloaded" Write-Host "" - # 3. Fetch CMSIS Core headers (standard ARM CMSIS-Core include files) - Write-Host "[INFO] Cloning CMSIS Core headers (depth=1)..." - $cmsisCloneDir = Join-Path $TempDir "cmsis_core_repo" - git clone --depth 1 https://github.com/ARM-software/CMSIS_5.git $cmsisCloneDir - if ($LASTEXITCODE -ne 0) { - throw "Failed to clone CMSIS Core repository" + # 3. Fetch CMSIS Core headers (pinned ARM.CMSIS 5.9.0 release pack from ARM-software/CMSIS_5) + $cmsisVersion = "5.9.0" + $cmsisPackUrl = "https://github.com/ARM-software/CMSIS_5/releases/download/$cmsisVersion/ARM.CMSIS.$cmsisVersion.pack" + $cmsisPackSha256 = "14b366f2821ee5d32f0d3bf48ef9657ca45347261d0531263580848e9d36f8f4" + $cmsisPackZip = Join-Path $TempDir "cmsis.zip" + $cmsisExtract = Join-Path $TempDir "cmsis_extracted" + + Write-Host "[INFO] Downloading official ARM CMSIS Pack (v$cmsisVersion)..." + Download-WithRetry -Uri $cmsisPackUrl -OutFile $cmsisPackZip -ExpectedHash $cmsisPackSha256 + Write-Host "[OK] ARM CMSIS Pack verified (SHA256: $cmsisPackSha256)" + + Write-Host "[INFO] Extracting CMSIS Core headers..." + New-Item -ItemType Directory -Path $cmsisExtract -Force | Out-Null + if (Get-Command tar.exe -ErrorAction SilentlyContinue) { + & tar.exe -xf $cmsisPackZip -C $cmsisExtract "CMSIS/Core/Include" + } else { + Expand-Archive -Path $cmsisPackZip -DestinationPath $cmsisExtract -Force } - Copy-Item -Path "$cmsisCloneDir/CMSIS/Core/Include/*" -Destination $CmsisIncludeDest -Recurse -Force + $cmsisSource = Join-Path $cmsisExtract "CMSIS/Core/Include" + Copy-Item -Path "$cmsisSource/*" -Destination $CmsisIncludeDest -Recurse -Force Write-Host "[OK] CMSIS Core headers copied" Write-Host "" - # 4. Fetch official NXP KSZ8081 PHY driver (100% stock upstream) - Write-Host "[INFO] Downloading official KSZ8081 PHY driver..." - $phyRawBase = "https://raw.githubusercontent.com/eclipse-threadx/getting-started/master/NXP/MIMXRT1060-EVK/lib/MIMXRT1060-evk/src/components/phyksz8081" - $phyDestDir = Join-Path $ComponentsDir "phy" - New-Item -ItemType Directory -Path $phyDestDir -Force | Out-Null - Download-WithRetry -Uri "$phyRawBase/fsl_phy.c" -OutFile (Join-Path $phyDestDir "fsl_phy.c") - Download-WithRetry -Uri "$phyRawBase/fsl_phy.h" -OutFile (Join-Path $phyDestDir "fsl_phy.h") - Write-Host "[OK] Stock KSZ8081 PHY driver downloaded" - Write-Host "" - - # 5. Fetch official NetX Duo NXP Ethernet driver (100% stock upstream) - Write-Host "[INFO] Downloading official NetX Duo NXP Ethernet driver..." - $netxRawBase = "https://raw.githubusercontent.com/eclipse-threadx/getting-started/master/NXP/MIMXRT1060-EVK/lib/netx_driver" - $netxDriverDestDir = Join-Path $DriversDir "netx_driver" - $netxDriverGnuDir = Join-Path $netxDriverDestDir "gnu" - New-Item -ItemType Directory -Path $netxDriverGnuDir -Force | Out-Null - Download-WithRetry -Uri "$netxRawBase/src/nx_driver_imxrt1062.c" -OutFile (Join-Path $netxDriverDestDir "nx_driver_imxrt1062.c") - Download-WithRetry -Uri "$netxRawBase/src/nx_driver_imxrt1062.h" -OutFile (Join-Path $netxDriverDestDir "nx_driver_imxrt1062.h") - Download-WithRetry -Uri "$netxRawBase/src/gnu/nx_driver_imxrt1062_low_level.S" -OutFile (Join-Path $netxDriverGnuDir "nx_driver_imxrt1062_low_level.S") - Write-Host "[OK] Stock NetX Duo NXP Ethernet driver downloaded" + Write-Host "[INFO] Note: NetX Duo Ethernet driver and KSZ8081 PHY driver are vendored in lib/netx_driver and lib/phyksz8081." Write-Host "" Write-Host "==========================================" - Write-Host "[SUCCESS] NXP i.MX RT1064 drivers successfully fetched!" + Write-Host "[SUCCESS] NXP i.MX RT1064 SDK dependencies successfully fetched & verified!" Write-Host "==========================================" } finally { diff --git a/targets/NXP/MIMXRT1064-EVK/scripts/fetch_sdk.sh b/targets/NXP/MIMXRT1064-EVK/scripts/fetch_sdk.sh new file mode 100644 index 00000000..b27b6744 --- /dev/null +++ b/targets/NXP/MIMXRT1064-EVK/scripts/fetch_sdk.sh @@ -0,0 +1,160 @@ +#!/usr/bin/env bash +# Copyright (c) 2026 Eclipse ThreadX contributors +# +# 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. + +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +BOARD_DIR="$(cd "${SCRIPT_DIR}/.." && pwd)" + +LIB_DIR="${BOARD_DIR}/lib/mcux-sdk" +DEVICE_DIR="${LIB_DIR}/devices/MIMXRT1064" +DRIVERS_DIR="${LIB_DIR}/drivers" +UTILITIES_DIR="${LIB_DIR}/utilities" +COMPONENTS_DIR="${LIB_DIR}/components" +BOARD_FILES_DIR="${LIB_DIR}/board" +CMSIS_INCLUDE_DEST="${LIB_DIR}/CMSIS/Include" +APP_STARTUP_DIR="${BOARD_DIR}/app/startup" +TEMP_DIR="${BOARD_DIR}/temp_fetch" + +echo "==========================================" +echo "NXP i.MX RT1064 Standalone Driver Fetcher (POSIX)" +echo "==========================================" +echo "Target Directory: ${LIB_DIR}" +echo "" + +# Helper to verify file integrity via sha256sum +verify_sha256() { + local file="$1" + local expected_sha="$2" + echo "${expected_sha} ${file}" | sha256sum --check --strict >/dev/null 2>&1 || { + echo "[ERROR] SHA256 checksum mismatch for ${file}!" >&2 + echo " Expected: ${expected_sha}" >&2 + echo " Actual: $(sha256sum "${file}" | awk '{print $1}')" >&2 + exit 1 + } +} + +# Helper to download and verify +fetch_and_verify() { + local url="$1" + local dest="$2" + local expected_sha="$3" + curl --retry 3 --retry-delay 2 -fsSL "${url}" -o "${dest}" + verify_sha256 "${dest}" "${expected_sha}" +} + +# Clean and recreate directories +rm -rf "${LIB_DIR}" +mkdir -p "${DEVICE_DIR}" +mkdir -p "${DRIVERS_DIR}" +mkdir -p "${UTILITIES_DIR}" +mkdir -p "${COMPONENTS_DIR}/uart" +mkdir -p "${BOARD_FILES_DIR}" +mkdir -p "${CMSIS_INCLUDE_DEST}" +mkdir -p "${APP_STARTUP_DIR}" + +rm -rf "${TEMP_DIR}" +mkdir -p "${TEMP_DIR}" + +clean_temp() { + if [ -d "${TEMP_DIR}" ]; then + rm -rf "${TEMP_DIR}" + fi +} +trap clean_temp EXIT + +# 1. Download official NXP MIMXRT1064 DFP pack from NXP repository (pinned v15.1.0) +PACK_URL="https://mcuxpresso.nxp.com/cmsis_pack/repo/NXP.MIMXRT1064_DFP.15.1.0.pack" +PACK_SHA256="14e02f0108beba1cfe9de6b2be7b1f874695614dcc16126c452bde1b68b509f6" +PACK_ZIP="${TEMP_DIR}/dfp.zip" +PACK_EXTRACT="${TEMP_DIR}/dfp_extracted" + +echo "[INFO] Downloading official NXP MIMXRT1064 Device Pack (v15.1.0)..." +fetch_and_verify "${PACK_URL}" "${PACK_ZIP}" "${PACK_SHA256}" +echo "[OK] NXP Device Pack verified (SHA256: ${PACK_SHA256})" + +echo "[INFO] Extracting Device Pack..." +mkdir -p "${PACK_EXTRACT}" +unzip -q "${PACK_ZIP}" -d "${PACK_EXTRACT}" + +# Copy device register headers & system files +for file in MIMXRT1064.h MIMXRT1064_features.h fsl_device_registers.h system_MIMXRT1064.c system_MIMXRT1064.h; do + cp "${PACK_EXTRACT}/${file}" "${DEVICE_DIR}/" +done + +# Copy core peripheral drivers +for file in fsl_clock.c fsl_clock.h fsl_common.c fsl_common.h fsl_common_arm.c fsl_common_arm.h fsl_gpio.c fsl_gpio.h fsl_lpuart.c fsl_lpuart.h fsl_enet.c fsl_enet.h fsl_iomuxc.h; do + cp "${PACK_EXTRACT}/drivers/${file}" "${DRIVERS_DIR}/" +done + +# Copy utilities (debug console & string formatting) +for file in utilities/debug_console_lite/fsl_debug_console.h \ + utilities/debug_console_lite/fsl_debug_console.c \ + utilities/debug_console_lite/fsl_assert.c \ + utilities/debug_console/fsl_debug_console_conf.h \ + utilities/str/fsl_str.c \ + utilities/str/fsl_str.h; do + cp "${PACK_EXTRACT}/${file}" "${UTILITIES_DIR}/" +done + +# Copy UART component adapter +for file in components/uart/fsl_adapter_uart.h components/uart/fsl_adapter_lpuart.c; do + cp "${PACK_EXTRACT}/${file}" "${COMPONENTS_DIR}/uart/" +done + +# Copy XIP flexspi boot headers +cp -r "${PACK_EXTRACT}/xip/"* "${DEVICE_DIR}/" +echo "[OK] NXP Device, Driver, Utility, and Component files copied" +echo "" + +# 2. Download EVK-MIMXRT1064 Board Support Files (pinned to commit 2a340e10 from nxp-mcuxpresso/mcuxsdk-examples) +MCUX_EXAMPLES_COMMIT="2a340e10a1105bc0af8e7176bc19148911f4cf12" +RAW_BASE="https://raw.githubusercontent.com/nxp-mcuxpresso/mcuxsdk-examples/${MCUX_EXAMPLES_COMMIT}/_boards/evkmimxrt1064" +echo "[INFO] Downloading EVK-MIMXRT1064 board support files (pinned: ${MCUX_EXAMPLES_COMMIT:0:8})..." + +fetch_and_verify "${RAW_BASE}/board.c" "${BOARD_FILES_DIR}/board.c" "f28885b9ac349a06a6b38f0376f6872a25ec131ab7d37947a0576255579cd959" +fetch_and_verify "${RAW_BASE}/board.h" "${BOARD_FILES_DIR}/board.h" "9c25debd61b7fc153eeedd569155dfc8f9d1349192c6de2b431742ee6f9bb17e" +fetch_and_verify "${RAW_BASE}/project_template/clock_config.c" "${BOARD_FILES_DIR}/clock_config.c" "ca20b253229ef02e74a9d0041173c5e1fc0c5c3df048a53be8b44e1e4218ef03" +fetch_and_verify "${RAW_BASE}/project_template/clock_config.h" "${BOARD_FILES_DIR}/clock_config.h" "52036470ef08b16daf7ed1382a8c3c0bcc123336afc2b07df807e793365b3e80" +fetch_and_verify "${RAW_BASE}/project_template/pin_mux.c" "${BOARD_FILES_DIR}/pin_mux.c" "4bf784e2685555e6297adccb78a27de5754e5320911bc503b5ab563577599c39" +fetch_and_verify "${RAW_BASE}/project_template/pin_mux.h" "${BOARD_FILES_DIR}/pin_mux.h" "f696267090a271e12d9c9f3ccb0e2dfb721025ddd3728b32ab33a9fb79acbc70" +fetch_and_verify "${RAW_BASE}/dcd.c" "${BOARD_FILES_DIR}/dcd.c" "798cd3fffea9b3b1917d6750d40735b6bc890e770f8d8b9167238220b0fae21f" +fetch_and_verify "${RAW_BASE}/dcd.h" "${BOARD_FILES_DIR}/dcd.h" "3a5268f0ccdc02aa6df55b3fca87171df35161cca0c3e15971ac082cdefde7a3" +fetch_and_verify "${RAW_BASE}/xip/evkmimxrt1064_flexspi_nor_config.c" "${BOARD_FILES_DIR}/evkmimxrt1064_flexspi_nor_config.c" "f6fa3d1e3a09c1a4a9d3fc44aed23513e12341e6db96aa3427c923e6b41c6e46" +fetch_and_verify "${RAW_BASE}/xip/evkmimxrt1064_flexspi_nor_config.h" "${BOARD_FILES_DIR}/evkmimxrt1064_flexspi_nor_config.h" "4073f8c6e09fccc879dcedb6fe79f679bc8c9840bb90a7f527279a9a021813d3" + +echo "[OK] Board support files verified & downloaded" +echo "" + +# 3. Fetch CMSIS Core headers (pinned ARM.CMSIS 5.9.0 release pack from ARM-software/CMSIS_5) +CMSIS_VERSION="5.9.0" +CMSIS_PACK_URL="https://github.com/ARM-software/CMSIS_5/releases/download/${CMSIS_VERSION}/ARM.CMSIS.${CMSIS_VERSION}.pack" +CMSIS_PACK_SHA256="14b366f2821ee5d32f0d3bf48ef9657ca45347261d0531263580848e9d36f8f4" +CMSIS_PACK_ZIP="${TEMP_DIR}/cmsis.zip" +CMSIS_EXTRACT="${TEMP_DIR}/cmsis_extracted" + +echo "[INFO] Downloading official ARM CMSIS Pack (v${CMSIS_VERSION})..." +fetch_and_verify "${CMSIS_PACK_URL}" "${CMSIS_PACK_ZIP}" "${CMSIS_PACK_SHA256}" +echo "[OK] ARM CMSIS Pack verified (SHA256: ${CMSIS_PACK_SHA256})" + +echo "[INFO] Extracting CMSIS Core headers..." +mkdir -p "${CMSIS_EXTRACT}" +unzip -q "${CMSIS_PACK_ZIP}" "CMSIS/Core/Include/*" -d "${CMSIS_EXTRACT}" +cp -r "${CMSIS_EXTRACT}/CMSIS/Core/Include/"* "${CMSIS_INCLUDE_DEST}/" +echo "[OK] CMSIS Core headers copied" +echo "" + +echo "[INFO] Note: NetX Duo Ethernet driver and KSZ8081 PHY driver are vendored in lib/netx_driver and lib/phyksz8081." +echo "" +echo "==========================================" +echo "[SUCCESS] NXP i.MX RT1064 SDK dependencies successfully fetched & verified!" +echo "==========================================" diff --git a/NXP/MIMXRT1064-EVK/scripts/simulate.ps1 b/targets/NXP/MIMXRT1064-EVK/scripts/simulate.ps1 similarity index 100% rename from NXP/MIMXRT1064-EVK/scripts/simulate.ps1 rename to targets/NXP/MIMXRT1064-EVK/scripts/simulate.ps1 diff --git a/NXP/MIMXRT1064-EVK/scripts/simulate.sh b/targets/NXP/MIMXRT1064-EVK/scripts/simulate.sh similarity index 100% rename from NXP/MIMXRT1064-EVK/scripts/simulate.sh rename to targets/NXP/MIMXRT1064-EVK/scripts/simulate.sh diff --git a/NXP/MIMXRT1064-EVK/scripts/test_headless.ps1 b/targets/NXP/MIMXRT1064-EVK/scripts/test_headless.ps1 similarity index 100% rename from NXP/MIMXRT1064-EVK/scripts/test_headless.ps1 rename to targets/NXP/MIMXRT1064-EVK/scripts/test_headless.ps1 diff --git a/NXP/MIMXRT1064-EVK/scripts/test_headless.sh b/targets/NXP/MIMXRT1064-EVK/scripts/test_headless.sh similarity index 100% rename from NXP/MIMXRT1064-EVK/scripts/test_headless.sh rename to targets/NXP/MIMXRT1064-EVK/scripts/test_headless.sh diff --git a/NXP/MIMXRT1064-EVK/scripts/test_renode.py b/targets/NXP/MIMXRT1064-EVK/scripts/test_renode.py similarity index 98% rename from NXP/MIMXRT1064-EVK/scripts/test_renode.py rename to targets/NXP/MIMXRT1064-EVK/scripts/test_renode.py index b59b8d5f..17a42f8f 100644 --- a/NXP/MIMXRT1064-EVK/scripts/test_renode.py +++ b/targets/NXP/MIMXRT1064-EVK/scripts/test_renode.py @@ -106,7 +106,9 @@ def run_test(demo_name, seed=None, timeout_seconds=300): client_elf = os.path.join(demo_dir, "mimxrt1064_client.elf") if not os.path.isfile(client_elf): fallback_c = os.path.join(build_dir, "mimxrt1064_client.elf") - if not os.path.isfile(fallback_c): + if os.path.isfile(fallback_c): + client_elf = fallback_c + else: print(f"[FAIL] Client ELF binary not found: {client_elf}") return 1 From 55062b5da685c15cd637353915fdac289596882e Mon Sep 17 00:00:00 2001 From: Ali Eissa Date: Wed, 16 Sep 2026 17:27:38 +0400 Subject: [PATCH 11/11] docs(mimxrt1064-evk) fixed some file headers. Signed-off-by: Ali Eissa Assisted-by: Google DeepMind Antigravity --- .../MIMXRT1064-EVK/app/demos/netx_trng_console/client_main.c | 1 + targets/NXP/MIMXRT1064-EVK/app/demos/netx_trng_console/main.c | 1 + targets/NXP/MIMXRT1064-EVK/app/sysmem.c | 1 + targets/NXP/MIMXRT1064-EVK/app/trng.c | 1 + targets/NXP/MIMXRT1064-EVK/app/trng.h | 1 + targets/NXP/MIMXRT1064-EVK/lib/bsp/include/board_config.h | 4 ++++ targets/NXP/MIMXRT1064-EVK/lib/bsp/src/bsp_board.c | 4 ++++ targets/NXP/MIMXRT1064-EVK/lib/bsp/src/bsp_console.c | 4 ++++ targets/NXP/MIMXRT1064-EVK/lib/bsp/src/bsp_led.c | 4 ++++ targets/NXP/MIMXRT1064-EVK/lib/bsp/src/bsp_memory.c | 4 ++++ targets/NXP/MIMXRT1064-EVK/lib/bsp/src/bsp_selftest.c | 4 ++++ targets/NXP/MIMXRT1064-EVK/renode/mimxrt1064-evk.repl | 3 ++- targets/NXP/MIMXRT1064-EVK/scripts/test_headless.ps1 | 2 +- targets/NXP/MIMXRT1064-EVK/scripts/test_headless.sh | 2 +- targets/NXP/MIMXRT1064-EVK/scripts/test_renode.py | 3 ++- 15 files changed, 35 insertions(+), 4 deletions(-) diff --git a/targets/NXP/MIMXRT1064-EVK/app/demos/netx_trng_console/client_main.c b/targets/NXP/MIMXRT1064-EVK/app/demos/netx_trng_console/client_main.c index 048bc25f..77da5370 100644 --- a/targets/NXP/MIMXRT1064-EVK/app/demos/netx_trng_console/client_main.c +++ b/targets/NXP/MIMXRT1064-EVK/app/demos/netx_trng_console/client_main.c @@ -9,6 +9,7 @@ * * Contributors: * Ali Eissa - 2026 version. + * Assisted-by: Google DeepMind Antigravity (Gemini 3.8 Flash) */ #include diff --git a/targets/NXP/MIMXRT1064-EVK/app/demos/netx_trng_console/main.c b/targets/NXP/MIMXRT1064-EVK/app/demos/netx_trng_console/main.c index cba21c29..b9e1852c 100644 --- a/targets/NXP/MIMXRT1064-EVK/app/demos/netx_trng_console/main.c +++ b/targets/NXP/MIMXRT1064-EVK/app/demos/netx_trng_console/main.c @@ -9,6 +9,7 @@ * * Contributors: * Ali Eissa - 2026 version. + * Assisted-by: Google DeepMind Antigravity (Gemini 3.8 Flash) */ #include diff --git a/targets/NXP/MIMXRT1064-EVK/app/sysmem.c b/targets/NXP/MIMXRT1064-EVK/app/sysmem.c index 1b10a489..0f2dfe23 100644 --- a/targets/NXP/MIMXRT1064-EVK/app/sysmem.c +++ b/targets/NXP/MIMXRT1064-EVK/app/sysmem.c @@ -9,6 +9,7 @@ * * Contributors: * Ali Eissa - 2026 version. + * Assisted-by: Google DeepMind Antigravity (Gemini 3.8 Flash) */ #include "tx_api.h" diff --git a/targets/NXP/MIMXRT1064-EVK/app/trng.c b/targets/NXP/MIMXRT1064-EVK/app/trng.c index 428be528..c749a5c1 100644 --- a/targets/NXP/MIMXRT1064-EVK/app/trng.c +++ b/targets/NXP/MIMXRT1064-EVK/app/trng.c @@ -9,6 +9,7 @@ * * Contributors: * Ali Eissa - 2026 version. + * Assisted-by: Google DeepMind Antigravity (Gemini 3.8 Flash) */ #include "trng.h" diff --git a/targets/NXP/MIMXRT1064-EVK/app/trng.h b/targets/NXP/MIMXRT1064-EVK/app/trng.h index 6e1c0aa9..fbb364b6 100644 --- a/targets/NXP/MIMXRT1064-EVK/app/trng.h +++ b/targets/NXP/MIMXRT1064-EVK/app/trng.h @@ -9,6 +9,7 @@ * * Contributors: * Ali Eissa - 2026 version. + * Assisted-by: Google DeepMind Antigravity (Gemini 3.8 Flash) */ #ifndef TRNG_H diff --git a/targets/NXP/MIMXRT1064-EVK/lib/bsp/include/board_config.h b/targets/NXP/MIMXRT1064-EVK/lib/bsp/include/board_config.h index 237bb395..c6c9572f 100644 --- a/targets/NXP/MIMXRT1064-EVK/lib/bsp/include/board_config.h +++ b/targets/NXP/MIMXRT1064-EVK/lib/bsp/include/board_config.h @@ -6,6 +6,10 @@ * https://opensource.org/licenses/MIT. * * SPDX-License-Identifier: MIT + * + * Contributors: + * Ali Eissa - 2026 version. + * Assisted-by: Google DeepMind Antigravity (Gemini 3.8 Flash) */ #ifndef BOARD_CONFIG_H diff --git a/targets/NXP/MIMXRT1064-EVK/lib/bsp/src/bsp_board.c b/targets/NXP/MIMXRT1064-EVK/lib/bsp/src/bsp_board.c index 2dc26966..a5018a59 100644 --- a/targets/NXP/MIMXRT1064-EVK/lib/bsp/src/bsp_board.c +++ b/targets/NXP/MIMXRT1064-EVK/lib/bsp/src/bsp_board.c @@ -6,6 +6,10 @@ * https://opensource.org/licenses/MIT. * * SPDX-License-Identifier: MIT + * + * Contributors: + * Ali Eissa - 2026 version. + * Assisted-by: Google DeepMind Antigravity (Gemini 3.8 Flash) */ #include "bsp/board.h" diff --git a/targets/NXP/MIMXRT1064-EVK/lib/bsp/src/bsp_console.c b/targets/NXP/MIMXRT1064-EVK/lib/bsp/src/bsp_console.c index d5c7a54c..ee3910d4 100644 --- a/targets/NXP/MIMXRT1064-EVK/lib/bsp/src/bsp_console.c +++ b/targets/NXP/MIMXRT1064-EVK/lib/bsp/src/bsp_console.c @@ -6,6 +6,10 @@ * https://opensource.org/licenses/MIT. * * SPDX-License-Identifier: MIT + * + * Contributors: + * Ali Eissa - 2026 version. + * Assisted-by: Google DeepMind Antigravity (Gemini 3.8 Flash) */ #include "bsp/console.h" diff --git a/targets/NXP/MIMXRT1064-EVK/lib/bsp/src/bsp_led.c b/targets/NXP/MIMXRT1064-EVK/lib/bsp/src/bsp_led.c index 3b2ae78f..59ecb493 100644 --- a/targets/NXP/MIMXRT1064-EVK/lib/bsp/src/bsp_led.c +++ b/targets/NXP/MIMXRT1064-EVK/lib/bsp/src/bsp_led.c @@ -6,6 +6,10 @@ * https://opensource.org/licenses/MIT. * * SPDX-License-Identifier: MIT + * + * Contributors: + * Ali Eissa - 2026 version. + * Assisted-by: Google DeepMind Antigravity (Gemini 3.8 Flash) */ #include "bsp/led.h" diff --git a/targets/NXP/MIMXRT1064-EVK/lib/bsp/src/bsp_memory.c b/targets/NXP/MIMXRT1064-EVK/lib/bsp/src/bsp_memory.c index 7f834ba4..a9aacd21 100644 --- a/targets/NXP/MIMXRT1064-EVK/lib/bsp/src/bsp_memory.c +++ b/targets/NXP/MIMXRT1064-EVK/lib/bsp/src/bsp_memory.c @@ -6,6 +6,10 @@ * https://opensource.org/licenses/MIT. * * SPDX-License-Identifier: MIT + * + * Contributors: + * Ali Eissa - 2026 version. + * Assisted-by: Google DeepMind Antigravity (Gemini 3.8 Flash) */ #include "bsp/memory.h" diff --git a/targets/NXP/MIMXRT1064-EVK/lib/bsp/src/bsp_selftest.c b/targets/NXP/MIMXRT1064-EVK/lib/bsp/src/bsp_selftest.c index df164a08..22c3d81e 100644 --- a/targets/NXP/MIMXRT1064-EVK/lib/bsp/src/bsp_selftest.c +++ b/targets/NXP/MIMXRT1064-EVK/lib/bsp/src/bsp_selftest.c @@ -6,6 +6,10 @@ * https://opensource.org/licenses/MIT. * * SPDX-License-Identifier: MIT + * + * Contributors: + * Ali Eissa - 2026 version. + * Assisted-by: Google DeepMind Antigravity (Gemini 3.8 Flash) */ #include "bsp/selftest.h" diff --git a/targets/NXP/MIMXRT1064-EVK/renode/mimxrt1064-evk.repl b/targets/NXP/MIMXRT1064-EVK/renode/mimxrt1064-evk.repl index 303e5475..67acd0a6 100644 --- a/targets/NXP/MIMXRT1064-EVK/renode/mimxrt1064-evk.repl +++ b/targets/NXP/MIMXRT1064-EVK/renode/mimxrt1064-evk.repl @@ -6,7 +6,8 @@ // // SPDX-License-Identifier: MIT // -// Platform description for NXP i.MX RT1064-EVK (Simulated in Renode). +// Contributors: +// Ali Eissa - 2026 version. using "platforms/boards/mimxrt1064_evk.repl" diff --git a/targets/NXP/MIMXRT1064-EVK/scripts/test_headless.ps1 b/targets/NXP/MIMXRT1064-EVK/scripts/test_headless.ps1 index e23e0f62..64dae41a 100644 --- a/targets/NXP/MIMXRT1064-EVK/scripts/test_headless.ps1 +++ b/targets/NXP/MIMXRT1064-EVK/scripts/test_headless.ps1 @@ -7,7 +7,7 @@ # SPDX-License-Identifier: MIT # # Contributors: -# Ali Eissa - 2026 NXP i.MX RT1064 port. +# Ali Eissa - 2026 version. param( [string]$Demo = "threadx_basic", diff --git a/targets/NXP/MIMXRT1064-EVK/scripts/test_headless.sh b/targets/NXP/MIMXRT1064-EVK/scripts/test_headless.sh index 24bbc030..8222ce83 100644 --- a/targets/NXP/MIMXRT1064-EVK/scripts/test_headless.sh +++ b/targets/NXP/MIMXRT1064-EVK/scripts/test_headless.sh @@ -8,7 +8,7 @@ # SPDX-License-Identifier: MIT # # Contributors: -# Ali Eissa - 2026 NXP i.MX RT1064 port. +# Ali Eissa - 2026 version. set -e diff --git a/targets/NXP/MIMXRT1064-EVK/scripts/test_renode.py b/targets/NXP/MIMXRT1064-EVK/scripts/test_renode.py index 17a42f8f..befabdd0 100644 --- a/targets/NXP/MIMXRT1064-EVK/scripts/test_renode.py +++ b/targets/NXP/MIMXRT1064-EVK/scripts/test_renode.py @@ -9,7 +9,8 @@ # SPDX-License-Identifier: MIT # # Contributors: -# Ali Eissa - 2026 NXP i.MX RT1064 port. +# Ali Eissa - 2026 version. +# Assisted-by: Google DeepMind Antigravity (Gemini 3.8 Flash) """ Headless Renode Verification Test for NXP i.MX RT1064-EVK Demos.