diff --git a/cmake/utilities.cmake b/cmake/utilities.cmake deleted file mode 100644 index 2686c1f..0000000 --- a/cmake/utilities.cmake +++ /dev/null @@ -1,50 +0,0 @@ -# Copyright (c) Microsoft -# Copyright (c) 2024 Eclipse Foundation -# -# 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: -# Microsoft - Initial version -# Frédéric Desbiens - 2024 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/docs/architecture.md b/docs/architecture.md index e004969..b932fcb 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -9,8 +9,8 @@ This document describes the architecture, design philosophy, directory structure The BSP framework is designed to be **additive and non-invasive**, allowing new boards to be integrated without modifying existing board implementations. 1. **Legacy Isolation**: The board directories that predate this framework (`/MXChip`, `/OpenHW`, `/STMicroelectronics`) remain completely untouched, preserving their drivers, submodules, and build systems. -2. **Platform-Independent Applications**: Target applications use only the abstract BSP interfaces and have no compile-time dependency on vendor-specific HALs, SDKs, or hardware registers. -3. **Reusable Infrastructure**: Shared CMake toolchains and build utilities are centralized under `/cmake` to eliminate duplicated build configuration across supported boards. +2. **Hardware Access Through the BSP**: Application logic reaches LEDs and the console through the abstract interfaces in `/bsp`, not through vendor registers. Applications are target-resident: each target owns its demo under `app/`, and today's demos do additionally include their own `board_config.h` for memory sizing and vendor headers for board-specific startup self-tests. A fully portable shared application layer is a goal of the framework, not a property it has yet. +3. **Independent Build Configuration**: Each target carries its own `cmake/` toolchain files and build helpers. Nothing in the build is shared between targets, so changing one board cannot break another. --- @@ -24,11 +24,12 @@ samplex/ (repository root) ├── OpenHW/ # [Pre-framework] Standalone board sample ├── STMicroelectronics/ # [Pre-framework] Standalone board samples ├── targets/ # [Framework] Supported BSP target boards -│ └── Microchip/ -│ └── POLARFIRE_ICICLE_RENODE/ # Board-specific BSP implementation & Renode target +│ ├── Microchip/ +│ │ └── POLARFIRE_ICICLE_RENODE/ # Board-specific BSP implementation & Renode target +│ └── STMicroelectronics/ +│ └── NUCLEO_F401RE/ # Board-specific BSP implementation & Renode target ├── bsp/ # [Framework] Abstract BSP interface definitions │ └── include/bsp/ # board.h, led.h, console.h -├── cmake/ # [Framework] Shared CMake configuration and utilities ├── docs/ # [Framework] Architecture and onboarding documentation └── templates/ # [Framework] Templates for onboarding new boards ``` @@ -62,6 +63,6 @@ Every board added to the framework under `/targets` must implement the abstract 1. **Create the Target Folder**: Create a new directory under `targets///` using `/templates/target/` as the starting point. 2. **Define Local Configuration**: Create a `board_config.h` file containing board-specific settings such as clock configuration, UART parameters, and ThreadX memory allocation. 3. **Implement the BSP APIs**: Implement the interfaces defined in `/bsp/include/bsp/` using the vendor SDK or direct register access. -4. **Configure CMake**: Add the board target to `CMakeLists.txt`, build the BSP as a static library, and link it with the desired application from `/apps/`. +4. **Configure CMake**: Add the board target to `CMakeLists.txt`, supply the target's toolchain file under its own `cmake/`, build the BSP as a static library, and link it with the application in the target's `app/` directory. -Once a board implements the required BSP interfaces, any compatible application under `/apps` can be built for that board without modifying the application source. +Start from `templates/target/app/main.c`, which depends only on `` and the `` contracts and therefore builds on any target that implements them. Grow it in place as the board needs; there is no shared `/apps` directory to link an application from. diff --git a/templates/target/CMakeLists.txt b/templates/target/CMakeLists.txt index 13ac5b5..f68bc8d 100644 --- a/templates/target/CMakeLists.txt +++ b/templates/target/CMakeLists.txt @@ -11,20 +11,21 @@ cmake_minimum_required(VERSION 3.15) # TODO: Replace 'TARGET_BOARD_TEMPLATE' with your target board name (e.g. MY_CUSTOM_BOARD) project(TARGET_BOARD_TEMPLATE C CXX ASM) -set(CMAKE_C_STANDARD 11) +# AGENTS.md requires C99 compatibility. +set(CMAKE_C_STANDARD 99) set(CMAKE_C_STANDARD_REQUIRED ON) -# Define root paths +# Define root paths. Only libs/ and bsp/ are shared; the toolchain file and any +# CMake helper modules belong to this target, under cmake/. get_filename_component(WORKSPACE_ROOT "${CMAKE_CURRENT_LIST_DIR}/../../.." ABSOLUTE) set(SHARED_LIB_DIR "${WORKSPACE_ROOT}/libs") -set(SHARED_APP_DIR "${WORKSPACE_ROOT}/apps") set(SHARED_BSP_DIR "${WORKSPACE_ROOT}/bsp") -set(SHARED_CMAKE_DIR "${WORKSPACE_ROOT}/cmake") -# Include GNU ARM Toolchain setup if building for bare-metal ARM Cortex-M -if(EXISTS "${SHARED_CMAKE_DIR}/gcc-arm-none-eabi.cmake") - include("${SHARED_CMAKE_DIR}/gcc-arm-none-eabi.cmake") -endif() +# TODO: Add this target's cmake/ directory and select its toolchain file, e.g. +# if(NOT CMAKE_TOOLCHAIN_FILE) +# set(CMAKE_TOOLCHAIN_FILE "${CMAKE_CURRENT_LIST_DIR}/cmake/-toolchain.cmake") +# endif() +# list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}/cmake) # Global compiler flags add_compile_options( diff --git a/templates/target/README.md b/templates/target/README.md index 43a35a1..a5be06d 100644 --- a/templates/target/README.md +++ b/templates/target/README.md @@ -12,11 +12,11 @@ This directory contains the skeletal blueprint for onboarding a new hardware boa ## 1. Dependency Flow Architecture -The following diagram illustrates how the generic application layer is decoupled from physical MCU registers using the BSP framework: +The following diagram illustrates how application code reaches hardware through the BSP framework rather than through vendor registers directly: ```mermaid flowchart TD - App["Generic Application (apps/threadx_demo/main.c)"] + App["Application (targets/<Vendor>/<Board>/app/)"] BSP_API["BSP Interface Contract (bsp/include/bsp/)"] Target_BSP["Target BSP Driver Library (targets/<Vendor>/<Board>/lib/bsp/)"] Vendor_SDK["Vendor SDK / Platform Support Libraries"] @@ -33,9 +33,8 @@ flowchart TD ```text Repository │ -├── apps/ (Platform-independent application logic) ├── bsp/ (Target-agnostic C interface contracts) -├── cmake/ (Shared build infrastructure & toolchains) +├── libs/ (Shared RTOS components: ThreadX, NetX Duo, FileX, USBX) └── targets/ (Independent board support implementations) ├── STMicroelectronics/NUCLEO_F401RE/ └── Microchip/POLARFIRE_ICICLE_RENODE/ @@ -47,9 +46,11 @@ Repository To maintain long-term framework maintainability and portability, the following root directories should generally remain **unchanged** when onboarding a new board: -* `/apps`: Contains shared example applications and reusable demos (such as `threadx_demo`). Applications in this directory interact with hardware solely through the abstract headers in ``. Developers may also add additional applications alongside the provided examples. * `/bsp`: Defines the target-agnostic C interface contracts (`board.h`, `led.h`, `console.h`). New board targets must implement these existing interfaces rather than modifying core interface definitions. -* `/cmake`: Contains shared cross-compilation toolchain settings and build utility functions. +* `/libs`: Shared RTOS components consumed by every target as submodules. Targets reference these rather than vendoring their own copy. + +> [!NOTE] +> **Applications are currently target-resident.** Each target owns its demo under `targets///app/`, along with its own `cmake/` toolchain files and build helpers. A shared `/apps` layer is a goal of this framework, not something it provides yet: today's demos also include their target's `board_config.h` for memory sizing and vendor headers for board-specific startup self-tests. Onboard a new board by starting from the app in this template, not by linking one from a shared directory. > [!NOTE] > **Core Architectural Principle**: @@ -74,7 +75,8 @@ The table below maps common embedded software components to their designated loc | **BSP Driver Implementation** | `targets///lib/bsp/src/` | Target developer (`bsp_board.c`, `bsp_led.c`, `bsp_console.c`) | | **Target Specification Constants** | `targets///lib/bsp/include/board_config.h` | Target developer (declarative defines only) | | **Target Build Automation** | `targets///scripts/build.ps1` | Target developer (PowerShell automation template) | -| **Shared Application Code** | `/apps//` | Framework shared application layer (remains in root) | +| **Application Code** | `targets///app/` | Target developer (start from this template's `app/main.c`) | +| **Toolchain & Build Helpers** | `targets///cmake/` | Target developer (cross-compilation settings per target) | --- diff --git a/templates/target/app/CMakeLists.txt b/templates/target/app/CMakeLists.txt index 1fad0ea..6e9a585 100644 --- a/templates/target/app/CMakeLists.txt +++ b/templates/target/app/CMakeLists.txt @@ -15,8 +15,9 @@ set(SOURCES # ${COMMON_DIR}/startup/startup_mcu.s # ${COMMON_DIR}/startup/tx_initialize_low_level.S - # Link the shared platform-independent ThreadX application - ${CMAKE_CURRENT_SOURCE_DIR}/../../../../apps/threadx_demo/main.c + # This target's ThreadX application. Applications are target-resident: + # there is no shared apps/ directory to link one from. + ${CMAKE_CURRENT_SOURCE_DIR}/main.c # Link GCC Newlib syscall stubs ${CMAKE_CURRENT_SOURCE_DIR}/../lib/bsp/src/newlib_stubs.c diff --git a/templates/target/app/main.c b/templates/target/app/main.c new file mode 100644 index 0000000..668cf68 --- /dev/null +++ b/templates/target/app/main.c @@ -0,0 +1,105 @@ +/*************************************************************************** + * 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. + * + * AI Disclosure: This file was largely AI-generated by Claude Code (Opus 5). + * The AI-generated portions may be considered public domain (CC0-1.0) + * and not subject to the project's licence. The human contributor has + * reviewed and verified that the code is correct. + * + * SPDX-License-Identifier: MIT and CC0-1.0 + **************************************************************************/ + +/* + * Minimal ThreadX starting point for a new board target. + * + * This file deliberately depends on nothing but and the generic BSP + * contracts in , so it compiles for any target that implements them. + * Thread stacks are static, which avoids needing the board's memory extents. + * + * Once the board boots this, grow the demo in place. Real targets do include + * their own board_config.h and vendor headers - for byte-pool sizing and for + * board-specific startup self-tests - and that is expected; applications live + * with their target rather than in a shared directory. + */ + +#include "tx_api.h" + +#include "bsp/board.h" +#include "bsp/console.h" +#include "bsp/led.h" + +#include + +#define DEMO_STACK_SIZE 1024 +#define BLINK_PERIOD_TICKS (TX_TIMER_TICKS_PER_SECOND / 2) +#define REPORT_PERIOD_TICKS (TX_TIMER_TICKS_PER_SECOND) + +static TX_THREAD blink_thread; +static TX_THREAD report_thread; + +static UCHAR blink_stack[DEMO_STACK_SIZE]; +static UCHAR report_stack[DEMO_STACK_SIZE]; + +static void console_print(const char *text) +{ + bsp_console_write(text, strlen(text)); +} + +static void blink_thread_entry(ULONG parameter) +{ + (void)parameter; + + while (1) + { + bsp_led_toggle(); + tx_thread_sleep(BLINK_PERIOD_TICKS); + } +} + +static void report_thread_entry(ULONG parameter) +{ + (void)parameter; + + while (1) + { + console_print("[template] ThreadX is running\r\n"); + tx_thread_sleep(REPORT_PERIOD_TICKS); + } +} + +void tx_application_define(void *first_unused_memory) +{ + (void)first_unused_memory; + + /* TODO: Create a TX_BYTE_POOL from first_unused_memory if this target's + * demo outgrows static stacks. Doing so needs the board's RAM extent, so + * it belongs with the target rather than in shared code. */ + + (void)tx_thread_create(&blink_thread, "blink thread", blink_thread_entry, 0, + blink_stack, DEMO_STACK_SIZE, + 10, 10, TX_NO_TIME_SLICE, TX_AUTO_START); + + (void)tx_thread_create(&report_thread, "report thread", report_thread_entry, 0, + report_stack, DEMO_STACK_SIZE, + 11, 11, TX_NO_TIME_SLICE, TX_AUTO_START); +} + +int main(void) +{ + bsp_board_init(); + + console_print("\r\n=== Eclipse ThreadX target template ===\r\n"); + + /* TODO: Run any board-specific startup self-tests here, before the + * scheduler starts, so failures are reported even if it never runs. */ + + tx_kernel_enter(); + + while (1) + { + } +} diff --git a/templates/target/lib/bsp/CMakeLists.txt b/templates/target/lib/bsp/CMakeLists.txt index de09666..8b7ddeb 100644 --- a/templates/target/lib/bsp/CMakeLists.txt +++ b/templates/target/lib/bsp/CMakeLists.txt @@ -16,7 +16,7 @@ add_library(target_bsp STATIC # Export BSP headers and shared abstract C BSP headers to PUBLIC include paths target_include_directories(target_bsp PUBLIC include - ${CMAKE_CURRENT_LIST_DIR}/../../../../../bsp/include + ${SHARED_BSP_DIR}/include ) # Link ThreadX and vendor HAL dependencies if required