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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 0 additions & 50 deletions cmake/utilities.cmake

This file was deleted.

15 changes: 8 additions & 7 deletions docs/architecture.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -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.

---

Expand All@@ -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
```
Expand DownExpand Up@@ -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/<Vendor>/<Board_Name>/` 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 `<tx_api.h>` and the `<bsp/...>` 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.
17 changes: 9 additions & 8 deletions templates/target/CMakeLists.txt
Original file line numberDiff line numberDiff line change
Expand Up@@ -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/<arch>-toolchain.cmake")
# endif()
# list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}/cmake)

# Global compiler flags
add_compile_options(
Expand Down
16 changes: 9 additions & 7 deletions templates/target/README.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -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/&lt;Vendor&gt;/&lt;Board&gt;/app/)"]
BSP_API["BSP Interface Contract (bsp/include/bsp/)"]
Target_BSP["Target BSP Driver Library (targets/&lt;Vendor&gt;/&lt;Board&gt;/lib/bsp/)"]
Vendor_SDK["Vendor SDK / Platform Support Libraries"]
Expand All@@ -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/
Expand All@@ -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 `<bsp/...>`. 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/<Vendor>/<Board>/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**:
Expand All@@ -74,7 +75,8 @@ The table below maps common embedded software components to their designated loc
| **BSP Driver Implementation** | `targets/<Vendor>/<BOARD>/lib/bsp/src/` | Target developer (`bsp_board.c`, `bsp_led.c`, `bsp_console.c`) |
| **Target Specification Constants** | `targets/<Vendor>/<BOARD>/lib/bsp/include/board_config.h` | Target developer (declarative defines only) |
| **Target Build Automation** | `targets/<Vendor>/<BOARD>/scripts/build.ps1` | Target developer (PowerShell automation template) |
| **Shared Application Code** | `/apps/<app_name>/` | Framework shared application layer (remains in root) |
| **Application Code** | `targets/<Vendor>/<BOARD>/app/` | Target developer (start from this template's `app/main.c`) |
| **Toolchain & Build Helpers** | `targets/<Vendor>/<BOARD>/cmake/` | Target developer (cross-compilation settings per target) |

---

Expand Down
5 changes: 3 additions & 2 deletions templates/target/app/CMakeLists.txt
Original file line numberDiff line numberDiff line change
Expand Up@@ -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
Expand Down
105 changes: 105 additions & 0 deletions templates/target/app/main.c
Original file line numberDiff line numberDiff line change
@@ -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 <tx_api.h> and the generic BSP
* contracts in <bsp/...>, 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 <string.h>

#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)
{
}
}
2 changes: 1 addition & 1 deletion templates/target/lib/bsp/CMakeLists.txt
Original file line numberDiff line numberDiff line change
Expand Up@@ -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
Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
 blocks
(function() {
function addCopyButtons() {
document.querySelectorAll('pre code').forEach(function(codeBlock) {
if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
codeBlock.parentElement.setAttribute('data-copy-added', 'true');
var btn = document.createElement('button');
btn.textContent = 'Copy';
btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';
btn.onmouseover = function() { this.style.opacity = '1'; };
btn.onmouseout = function() { this.style.opacity = '0.7'; };
btn.onclick = function() {
navigator.clipboard.writeText(codeBlock.textContent).then(function() {
btn.textContent = 'Copied!';
setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
});
};
codeBlock.parentElement.style.position = 'relative';
codeBlock.parentElement.appendChild(btn);
});
}
addCopyButtons();
// Re-run on dynamic content
var observer = new MutationObserver(addCopyButtons);
observer.observe(document.body, { childList: true, subtree: true });
})();
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Correct the target template to describe how the framework actually works by fdesbiens · Pull Request #52 · eclipse-threadx/samplex · GitHub
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 0 additions & 50 deletions cmake/utilities.cmake

This file was deleted.

15 changes: 8 additions & 7 deletions docs/architecture.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -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.

---

Expand All@@ -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
```
Expand DownExpand Up@@ -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/<Vendor>/<Board_Name>/` 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 `<tx_api.h>` and the `<bsp/...>` 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.
17 changes: 9 additions & 8 deletions templates/target/CMakeLists.txt
Original file line numberDiff line numberDiff line change
Expand Up@@ -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/<arch>-toolchain.cmake")
# endif()
# list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}/cmake)

# Global compiler flags
add_compile_options(
Expand Down
16 changes: 9 additions & 7 deletions templates/target/README.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -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/&lt;Vendor&gt;/&lt;Board&gt;/app/)"]
BSP_API["BSP Interface Contract (bsp/include/bsp/)"]
Target_BSP["Target BSP Driver Library (targets/&lt;Vendor&gt;/&lt;Board&gt;/lib/bsp/)"]
Vendor_SDK["Vendor SDK / Platform Support Libraries"]
Expand All@@ -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/
Expand All@@ -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 `<bsp/...>`. 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/<Vendor>/<Board>/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**:
Expand All@@ -74,7 +75,8 @@ The table below maps common embedded software components to their designated loc
| **BSP Driver Implementation** | `targets/<Vendor>/<BOARD>/lib/bsp/src/` | Target developer (`bsp_board.c`, `bsp_led.c`, `bsp_console.c`) |
| **Target Specification Constants** | `targets/<Vendor>/<BOARD>/lib/bsp/include/board_config.h` | Target developer (declarative defines only) |
| **Target Build Automation** | `targets/<Vendor>/<BOARD>/scripts/build.ps1` | Target developer (PowerShell automation template) |
| **Shared Application Code** | `/apps/<app_name>/` | Framework shared application layer (remains in root) |
| **Application Code** | `targets/<Vendor>/<BOARD>/app/` | Target developer (start from this template's `app/main.c`) |
| **Toolchain & Build Helpers** | `targets/<Vendor>/<BOARD>/cmake/` | Target developer (cross-compilation settings per target) |

---

Expand Down
5 changes: 3 additions & 2 deletions templates/target/app/CMakeLists.txt
Original file line numberDiff line numberDiff line change
Expand Up@@ -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
Expand Down
105 changes: 105 additions & 0 deletions templates/target/app/main.c
Original file line numberDiff line numberDiff line change
@@ -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 <tx_api.h> and the generic BSP
* contracts in <bsp/...>, 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 <string.h>

#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)
{
}
}
2 changes: 1 addition & 1 deletion templates/target/lib/bsp/CMakeLists.txt
Original file line numberDiff line numberDiff line change
Expand Up@@ -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
Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' Correct the target template to describe how the framework actually works by fdesbiens · Pull Request #52 · eclipse-threadx/samplex · GitHub
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 0 additions & 50 deletions cmake/utilities.cmake

This file was deleted.

15 changes: 8 additions & 7 deletions docs/architecture.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -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.

---

Expand All@@ -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
```
Expand DownExpand Up@@ -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/<Vendor>/<Board_Name>/` 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 `<tx_api.h>` and the `<bsp/...>` 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.
17 changes: 9 additions & 8 deletions templates/target/CMakeLists.txt
Original file line numberDiff line numberDiff line change
Expand Up@@ -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/<arch>-toolchain.cmake")
# endif()
# list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}/cmake)

# Global compiler flags
add_compile_options(
Expand Down
16 changes: 9 additions & 7 deletions templates/target/README.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -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/&lt;Vendor&gt;/&lt;Board&gt;/app/)"]
BSP_API["BSP Interface Contract (bsp/include/bsp/)"]
Target_BSP["Target BSP Driver Library (targets/&lt;Vendor&gt;/&lt;Board&gt;/lib/bsp/)"]
Vendor_SDK["Vendor SDK / Platform Support Libraries"]
Expand All@@ -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/
Expand All@@ -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 `<bsp/...>`. 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/<Vendor>/<Board>/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**:
Expand All@@ -74,7 +75,8 @@ The table below maps common embedded software components to their designated loc
| **BSP Driver Implementation** | `targets/<Vendor>/<BOARD>/lib/bsp/src/` | Target developer (`bsp_board.c`, `bsp_led.c`, `bsp_console.c`) |
| **Target Specification Constants** | `targets/<Vendor>/<BOARD>/lib/bsp/include/board_config.h` | Target developer (declarative defines only) |
| **Target Build Automation** | `targets/<Vendor>/<BOARD>/scripts/build.ps1` | Target developer (PowerShell automation template) |
| **Shared Application Code** | `/apps/<app_name>/` | Framework shared application layer (remains in root) |
| **Application Code** | `targets/<Vendor>/<BOARD>/app/` | Target developer (start from this template's `app/main.c`) |
| **Toolchain & Build Helpers** | `targets/<Vendor>/<BOARD>/cmake/` | Target developer (cross-compilation settings per target) |

---

Expand Down
5 changes: 3 additions & 2 deletions templates/target/app/CMakeLists.txt
Original file line numberDiff line numberDiff line change
Expand Up@@ -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
Expand Down
105 changes: 105 additions & 0 deletions templates/target/app/main.c
Original file line numberDiff line numberDiff line change
@@ -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 <tx_api.h> and the generic BSP
* contracts in <bsp/...>, 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 <string.h>

#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)
{
}
}
2 changes: 1 addition & 1 deletion templates/target/lib/bsp/CMakeLists.txt
Original file line numberDiff line numberDiff line change
Expand Up@@ -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
Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' Correct the target template to describe how the framework actually works by fdesbiens · Pull Request #52 · eclipse-threadx/samplex · GitHub
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 0 additions & 50 deletions cmake/utilities.cmake

This file was deleted.

15 changes: 8 additions & 7 deletions docs/architecture.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -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.

---

Expand All@@ -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
```
Expand DownExpand Up@@ -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/<Vendor>/<Board_Name>/` 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 `<tx_api.h>` and the `<bsp/...>` 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.
17 changes: 9 additions & 8 deletions templates/target/CMakeLists.txt
Original file line numberDiff line numberDiff line change
Expand Up@@ -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/<arch>-toolchain.cmake")
# endif()
# list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}/cmake)

# Global compiler flags
add_compile_options(
Expand Down
16 changes: 9 additions & 7 deletions templates/target/README.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -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/&lt;Vendor&gt;/&lt;Board&gt;/app/)"]
BSP_API["BSP Interface Contract (bsp/include/bsp/)"]
Target_BSP["Target BSP Driver Library (targets/&lt;Vendor&gt;/&lt;Board&gt;/lib/bsp/)"]
Vendor_SDK["Vendor SDK / Platform Support Libraries"]
Expand All@@ -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/
Expand All@@ -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 `<bsp/...>`. 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/<Vendor>/<Board>/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**:
Expand All@@ -74,7 +75,8 @@ The table below maps common embedded software components to their designated loc
| **BSP Driver Implementation** | `targets/<Vendor>/<BOARD>/lib/bsp/src/` | Target developer (`bsp_board.c`, `bsp_led.c`, `bsp_console.c`) |
| **Target Specification Constants** | `targets/<Vendor>/<BOARD>/lib/bsp/include/board_config.h` | Target developer (declarative defines only) |
| **Target Build Automation** | `targets/<Vendor>/<BOARD>/scripts/build.ps1` | Target developer (PowerShell automation template) |
| **Shared Application Code** | `/apps/<app_name>/` | Framework shared application layer (remains in root) |
| **Application Code** | `targets/<Vendor>/<BOARD>/app/` | Target developer (start from this template's `app/main.c`) |
| **Toolchain & Build Helpers** | `targets/<Vendor>/<BOARD>/cmake/` | Target developer (cross-compilation settings per target) |

---

Expand Down
5 changes: 3 additions & 2 deletions templates/target/app/CMakeLists.txt
Original file line numberDiff line numberDiff line change
Expand Up@@ -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
Expand Down
105 changes: 105 additions & 0 deletions templates/target/app/main.c
Original file line numberDiff line numberDiff line change
@@ -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 <tx_api.h> and the generic BSP
* contracts in <bsp/...>, 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 <string.h>

#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)
{
}
}
2 changes: 1 addition & 1 deletion templates/target/lib/bsp/CMakeLists.txt
Original file line numberDiff line numberDiff line change
Expand Up@@ -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
Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ' Correct the target template to describe how the framework actually works by fdesbiens · Pull Request #52 · eclipse-threadx/samplex · GitHub
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 0 additions & 50 deletions cmake/utilities.cmake

This file was deleted.

15 changes: 8 additions & 7 deletions docs/architecture.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -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.

---

Expand All@@ -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
```
Expand DownExpand Up@@ -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/<Vendor>/<Board_Name>/` 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 `<tx_api.h>` and the `<bsp/...>` 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.
17 changes: 9 additions & 8 deletions templates/target/CMakeLists.txt
Original file line numberDiff line numberDiff line change
Expand Up@@ -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/<arch>-toolchain.cmake")
# endif()
# list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}/cmake)

# Global compiler flags
add_compile_options(
Expand Down
16 changes: 9 additions & 7 deletions templates/target/README.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -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/&lt;Vendor&gt;/&lt;Board&gt;/app/)"]
BSP_API["BSP Interface Contract (bsp/include/bsp/)"]
Target_BSP["Target BSP Driver Library (targets/&lt;Vendor&gt;/&lt;Board&gt;/lib/bsp/)"]
Vendor_SDK["Vendor SDK / Platform Support Libraries"]
Expand All@@ -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/
Expand All@@ -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 `<bsp/...>`. 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/<Vendor>/<Board>/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**:
Expand All@@ -74,7 +75,8 @@ The table below maps common embedded software components to their designated loc
| **BSP Driver Implementation** | `targets/<Vendor>/<BOARD>/lib/bsp/src/` | Target developer (`bsp_board.c`, `bsp_led.c`, `bsp_console.c`) |
| **Target Specification Constants** | `targets/<Vendor>/<BOARD>/lib/bsp/include/board_config.h` | Target developer (declarative defines only) |
| **Target Build Automation** | `targets/<Vendor>/<BOARD>/scripts/build.ps1` | Target developer (PowerShell automation template) |
| **Shared Application Code** | `/apps/<app_name>/` | Framework shared application layer (remains in root) |
| **Application Code** | `targets/<Vendor>/<BOARD>/app/` | Target developer (start from this template's `app/main.c`) |
| **Toolchain & Build Helpers** | `targets/<Vendor>/<BOARD>/cmake/` | Target developer (cross-compilation settings per target) |

---

Expand Down
5 changes: 3 additions & 2 deletions templates/target/app/CMakeLists.txt
Original file line numberDiff line numberDiff line change
Expand Up@@ -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
Expand Down
105 changes: 105 additions & 0 deletions templates/target/app/main.c
Original file line numberDiff line numberDiff line change
@@ -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 <tx_api.h> and the generic BSP
* contracts in <bsp/...>, 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 <string.h>

#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)
{
}
}
2 changes: 1 addition & 1 deletion templates/target/lib/bsp/CMakeLists.txt
Original file line numberDiff line numberDiff line change
Expand Up@@ -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
Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' Correct the target template to describe how the framework actually works by fdesbiens · Pull Request #52 · eclipse-threadx/samplex · GitHub
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 0 additions & 50 deletions cmake/utilities.cmake

This file was deleted.

15 changes: 8 additions & 7 deletions docs/architecture.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -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.

---

Expand All@@ -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
```
Expand DownExpand Up@@ -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/<Vendor>/<Board_Name>/` 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 `<tx_api.h>` and the `<bsp/...>` 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.
17 changes: 9 additions & 8 deletions templates/target/CMakeLists.txt
Original file line numberDiff line numberDiff line change
Expand Up@@ -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/<arch>-toolchain.cmake")
# endif()
# list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}/cmake)

# Global compiler flags
add_compile_options(
Expand Down
16 changes: 9 additions & 7 deletions templates/target/README.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -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/&lt;Vendor&gt;/&lt;Board&gt;/app/)"]
BSP_API["BSP Interface Contract (bsp/include/bsp/)"]
Target_BSP["Target BSP Driver Library (targets/&lt;Vendor&gt;/&lt;Board&gt;/lib/bsp/)"]
Vendor_SDK["Vendor SDK / Platform Support Libraries"]
Expand All@@ -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/
Expand All@@ -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 `<bsp/...>`. 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/<Vendor>/<Board>/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**:
Expand All@@ -74,7 +75,8 @@ The table below maps common embedded software components to their designated loc
| **BSP Driver Implementation** | `targets/<Vendor>/<BOARD>/lib/bsp/src/` | Target developer (`bsp_board.c`, `bsp_led.c`, `bsp_console.c`) |
| **Target Specification Constants** | `targets/<Vendor>/<BOARD>/lib/bsp/include/board_config.h` | Target developer (declarative defines only) |
| **Target Build Automation** | `targets/<Vendor>/<BOARD>/scripts/build.ps1` | Target developer (PowerShell automation template) |
| **Shared Application Code** | `/apps/<app_name>/` | Framework shared application layer (remains in root) |
| **Application Code** | `targets/<Vendor>/<BOARD>/app/` | Target developer (start from this template's `app/main.c`) |
| **Toolchain & Build Helpers** | `targets/<Vendor>/<BOARD>/cmake/` | Target developer (cross-compilation settings per target) |

---

Expand Down
5 changes: 3 additions & 2 deletions templates/target/app/CMakeLists.txt
Original file line numberDiff line numberDiff line change
Expand Up@@ -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
Expand Down
105 changes: 105 additions & 0 deletions templates/target/app/main.c
Original file line numberDiff line numberDiff line change
@@ -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 <tx_api.h> and the generic BSP
* contracts in <bsp/...>, 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 <string.h>

#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)
{
}
}
2 changes: 1 addition & 1 deletion templates/target/lib/bsp/CMakeLists.txt
Original file line numberDiff line numberDiff line change
Expand Up@@ -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
Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' Correct the target template to describe how the framework actually works by fdesbiens · Pull Request #52 · eclipse-threadx/samplex · GitHub
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 0 additions & 50 deletions cmake/utilities.cmake

This file was deleted.

15 changes: 8 additions & 7 deletions docs/architecture.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -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.

---

Expand All@@ -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
```
Expand DownExpand Up@@ -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/<Vendor>/<Board_Name>/` 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 `<tx_api.h>` and the `<bsp/...>` 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.
17 changes: 9 additions & 8 deletions templates/target/CMakeLists.txt
Original file line numberDiff line numberDiff line change
Expand Up@@ -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/<arch>-toolchain.cmake")
# endif()
# list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}/cmake)

# Global compiler flags
add_compile_options(
Expand Down
16 changes: 9 additions & 7 deletions templates/target/README.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -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/&lt;Vendor&gt;/&lt;Board&gt;/app/)"]
BSP_API["BSP Interface Contract (bsp/include/bsp/)"]
Target_BSP["Target BSP Driver Library (targets/&lt;Vendor&gt;/&lt;Board&gt;/lib/bsp/)"]
Vendor_SDK["Vendor SDK / Platform Support Libraries"]
Expand All@@ -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/
Expand All@@ -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 `<bsp/...>`. 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/<Vendor>/<Board>/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**:
Expand All@@ -74,7 +75,8 @@ The table below maps common embedded software components to their designated loc
| **BSP Driver Implementation** | `targets/<Vendor>/<BOARD>/lib/bsp/src/` | Target developer (`bsp_board.c`, `bsp_led.c`, `bsp_console.c`) |
| **Target Specification Constants** | `targets/<Vendor>/<BOARD>/lib/bsp/include/board_config.h` | Target developer (declarative defines only) |
| **Target Build Automation** | `targets/<Vendor>/<BOARD>/scripts/build.ps1` | Target developer (PowerShell automation template) |
| **Shared Application Code** | `/apps/<app_name>/` | Framework shared application layer (remains in root) |
| **Application Code** | `targets/<Vendor>/<BOARD>/app/` | Target developer (start from this template's `app/main.c`) |
| **Toolchain & Build Helpers** | `targets/<Vendor>/<BOARD>/cmake/` | Target developer (cross-compilation settings per target) |

---

Expand Down
5 changes: 3 additions & 2 deletions templates/target/app/CMakeLists.txt
Original file line numberDiff line numberDiff line change
Expand Up@@ -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
Expand Down
105 changes: 105 additions & 0 deletions templates/target/app/main.c
Original file line numberDiff line numberDiff line change
@@ -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 <tx_api.h> and the generic BSP
* contracts in <bsp/...>, 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 <string.h>

#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)
{
}
}
2 changes: 1 addition & 1 deletion templates/target/lib/bsp/CMakeLists.txt
Original file line numberDiff line numberDiff line change
Expand Up@@ -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
Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { // Universal Dark Mode - works on any site (function() { var enabled = true; function applyDarkMode() { if (!enabled) return; // Create style element if it doesn't exist var style = document.getElementById('universal-dark-mode-style'); if (!style) { style = document.createElement('style'); style.id = 'universal-dark-mode-style'; document.head.appendChild(style); } // Dark mode CSS - inverts colors but preserves images/video style.textContent = ' /* Invert everything except media */ html { filter: invert(1) hue-rotate(180deg) !important; background: #1a1a2e !important; } /* Restore images, videos, iframes, canvas */ img, video, iframe, canvas, svg, picture, [style*="background-image"] { filter: invert(1) hue-rotate(180deg) !important; } /* Preserve specific elements that should not be inverted */ .no-dark-mode, .no-dark-mode *, [data-theme="light"], [data-theme="light"], .ace_editor, .ace_editor *, .CodeMirror, .CodeMirror *, .monaco-editor, .monaco-editor *, .markdown-body pre, .markdown-body pre *, .highlight, .highlight *, pre code, pre code * { filter: none !important; } /* Fix common UI elements */ .modal, .popup, .dropdown-menu, .tooltip, .popover { filter: invert(1) hue-rotate(180deg) !important; background: #2d2d44 !important; border-color: #444 !important; } /* Scrollbars */ ::-webkit-scrollbar { background: #1a1a2e !important; } ::-webkit-scrollbar-thumb { background: #444 !important; } ::-webkit-scrollbar-thumb:hover { background: #555 !important; } /* Selection */ ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; } ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; } '; } function removeDarkMode() { var style = document.getElementById('universal-dark-mode-style'); if (style) style.remove(); } // Toggle with Alt+Shift+D document.addEventListener('keydown', function(e) { if (e.altKey && e.shiftKey && e.key === 'D') { e.preventDefault(); enabled = !enabled; if (enabled) { applyDarkMode(); console.log('[Universal Dark Mode] Enabled'); } else { removeDarkMode(); console.log('[Universal Dark Mode] Disabled'); } } }); // Apply on load applyDarkMode(); // Re-apply on dynamic content var observer = new MutationObserver(function(mutations) { if (enabled && !document.getElementById('universal-dark-mode-style')) { applyDarkMode(); } }); observer.observe(document.head, { childList: true }); console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle'); })(); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })(); Correct the target template to describe how the framework actually works by fdesbiens · Pull Request #52 · eclipse-threadx/samplex · GitHub
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 0 additions & 50 deletions cmake/utilities.cmake

This file was deleted.

15 changes: 8 additions & 7 deletions docs/architecture.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -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.

---

Expand All@@ -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
```
Expand DownExpand Up@@ -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/<Vendor>/<Board_Name>/` 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 `<tx_api.h>` and the `<bsp/...>` 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.
17 changes: 9 additions & 8 deletions templates/target/CMakeLists.txt
Original file line numberDiff line numberDiff line change
Expand Up@@ -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/<arch>-toolchain.cmake")
# endif()
# list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}/cmake)

# Global compiler flags
add_compile_options(
Expand Down
16 changes: 9 additions & 7 deletions templates/target/README.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -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/&lt;Vendor&gt;/&lt;Board&gt;/app/)"]
BSP_API["BSP Interface Contract (bsp/include/bsp/)"]
Target_BSP["Target BSP Driver Library (targets/&lt;Vendor&gt;/&lt;Board&gt;/lib/bsp/)"]
Vendor_SDK["Vendor SDK / Platform Support Libraries"]
Expand All@@ -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/
Expand All@@ -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 `<bsp/...>`. 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/<Vendor>/<Board>/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**:
Expand All@@ -74,7 +75,8 @@ The table below maps common embedded software components to their designated loc
| **BSP Driver Implementation** | `targets/<Vendor>/<BOARD>/lib/bsp/src/` | Target developer (`bsp_board.c`, `bsp_led.c`, `bsp_console.c`) |
| **Target Specification Constants** | `targets/<Vendor>/<BOARD>/lib/bsp/include/board_config.h` | Target developer (declarative defines only) |
| **Target Build Automation** | `targets/<Vendor>/<BOARD>/scripts/build.ps1` | Target developer (PowerShell automation template) |
| **Shared Application Code** | `/apps/<app_name>/` | Framework shared application layer (remains in root) |
| **Application Code** | `targets/<Vendor>/<BOARD>/app/` | Target developer (start from this template's `app/main.c`) |
| **Toolchain & Build Helpers** | `targets/<Vendor>/<BOARD>/cmake/` | Target developer (cross-compilation settings per target) |

---

Expand Down
5 changes: 3 additions & 2 deletions templates/target/app/CMakeLists.txt
Original file line numberDiff line numberDiff line change
Expand Up@@ -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
Expand Down
105 changes: 105 additions & 0 deletions templates/target/app/main.c
Original file line numberDiff line numberDiff line change
@@ -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 <tx_api.h> and the generic BSP
* contracts in <bsp/...>, 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 <string.h>

#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)
{
}
}
2 changes: 1 addition & 1 deletion templates/target/lib/bsp/CMakeLists.txt
Original file line numberDiff line numberDiff line change
Expand Up@@ -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
Expand Down
Loading