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

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions .github/workflows/ci_cortex_m.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,12 @@ on:
- 'ports/cortex_m3/gnu/**'
- 'ports/cortex_m4/gnu/**'
- 'ports/cortex_m7/gnu/**'
- 'ports_module/cortex_m0+/gnu/**'
- 'ports_module/cortex_m3/gnu/**'
- 'ports_module/cortex_m4/gnu/**'
- 'ports_module/cortex_m7/gnu/**'
- 'common_modules/**'
- 'CMakeLists.txt'

jobs:
build:
Expand Down Expand Up @@ -111,3 +117,12 @@ jobs:

- name: Compile and link
run: cmake --build ./build

- name: Prepare build system (module manager)
run: cmake -Bbuild-mm -DCMAKE_TOOLCHAIN_FILE=./cmake/cortex_m${{ matrix.port }}.cmake -DTHREADX_MODULE_MANAGER=ON -GNinja .

- name: Compile and link (module manager)
run: |
cmake --build ./build-mm
cmake --build ./build-mm --target threadx-module-manager-consumer-check

63 changes: 61 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ if(NOT ((THREADX_ARCH STREQUAL "win32") OR (THREADX_ARCH STREQUAL "win64")))
endif()

option(THREADX_SMP "Build ThreadX SMP version" OFF)
option(THREADX_MODULE_MANAGER "Build ThreadX kernel with module manager support" OFF)

# Enable testing at the top level so that tests registered by ports and
# example builds further down the tree are discoverable with ctest from the
Expand All @@ -31,7 +32,33 @@ option(THREADX_SMP "Build ThreadX SMP version" OFF)
# "ctest --test-dir <build>" reports no tests at all.
enable_testing()

if(THREADX_SMP)
if(THREADX_MODULE_MANAGER)
set(TX_PORT_DIR "ports_module")
if(THREADX_SMP)
set(TX_COMMON_DIR "common_smp")
if(THREADX_ARCH MATCHES "_smp$")
set(TX_ARCH_DIR "${THREADX_ARCH}")
else()
set(TX_ARCH_DIR "${THREADX_ARCH}_smp")
endif()
message(STATUS "Building ThreadX module manager SMP version")
else()
set(TX_COMMON_DIR "common")
set(TX_ARCH_DIR "${THREADX_ARCH}")
if(THREADX_ARCH STREQUAL "cortex_m0" AND NOT IS_DIRECTORY "${CMAKE_CURRENT_LIST_DIR}/${TX_PORT_DIR}/${TX_ARCH_DIR}")
set(TX_ARCH_DIR "cortex_m0+")
endif()
if(THREADX_ARCH MATCHES "_smp$")
message(FATAL_ERROR "ThreadX module manager SMP port '${THREADX_ARCH}' requires THREADX_SMP=ON")
endif()
message(STATUS "Building ThreadX module manager version")
endif()

set(TX_PORT_PATH "${CMAKE_CURRENT_LIST_DIR}/${TX_PORT_DIR}/${TX_ARCH_DIR}/${THREADX_TOOLCHAIN}")
if(NOT IS_DIRECTORY "${TX_PORT_PATH}/module_manager/src")
message(FATAL_ERROR "ThreadX module manager is not supported for architecture '${THREADX_ARCH}' with toolchain '${THREADX_TOOLCHAIN}' (SMP=${THREADX_SMP})")
endif()
elseif(THREADX_SMP)
set(TX_PORT_DIR "ports_smp")
set(TX_COMMON_DIR "common_smp")
set(TX_ARCH_DIR "${THREADX_ARCH}_smp")
Expand All @@ -43,11 +70,13 @@ if(THREADX_SMP)
set(TX_ARCH_DIR "${THREADX_ARCH}")
endif()
message(STATUS "Building ThreadX SMP version")
set(TX_PORT_PATH "${CMAKE_CURRENT_LIST_DIR}/${TX_PORT_DIR}/${TX_ARCH_DIR}/${THREADX_TOOLCHAIN}")
else()
set(TX_PORT_DIR "ports")
set(TX_COMMON_DIR "common")
set(TX_ARCH_DIR "${THREADX_ARCH}")
message(STATUS "Building standard ThreadX version")
set(TX_PORT_PATH "${CMAKE_CURRENT_LIST_DIR}/${TX_PORT_DIR}/${TX_ARCH_DIR}/${THREADX_TOOLCHAIN}")
endif()

message(STATUS "THREADX_ARCH: ${THREADX_ARCH}")
Expand All @@ -63,12 +92,39 @@ set(CUSTOM_INC_DIR ${CMAKE_CURRENT_BINARY_DIR}/custom_inc)
# Pick up the port specific variables and apply them
if(DEFINED THREADX_CUSTOM_PORT)
add_subdirectory(${THREADX_CUSTOM_PORT} threadx_port)
elseif(EXISTS "${TX_PORT_PATH}/CMakeLists.txt")
add_subdirectory(${TX_PORT_PATH})
elseif(THREADX_MODULE_MANAGER)
file(GLOB TX_PORT_SOURCES
"${TX_PORT_PATH}/module_manager/src/*.c"
"${TX_PORT_PATH}/module_manager/src/*.S"
"${TX_PORT_PATH}/module_manager/src/*.s"
)
if(THREADX_ARCH STREQUAL "cortex_r52")
file(GLOB TX_R52_BASE_SOURCES
"${CMAKE_CURRENT_LIST_DIR}/ports/cortex_r52/gnu/src/tx_thread_fiq_*.S"
"${CMAKE_CURRENT_LIST_DIR}/ports/cortex_r52/gnu/src/tx_thread_irq_*.S"
"${CMAKE_CURRENT_LIST_DIR}/ports/cortex_r52/gnu/src/tx_thread_interrupt_*.S"
"${CMAKE_CURRENT_LIST_DIR}/ports/cortex_r52/gnu/src/tx_thread_vectored_context_save.S"
"${CMAKE_CURRENT_LIST_DIR}/ports/cortex_r52/gnu/src/tx_timer_interrupt.S"
)
list(APPEND TX_PORT_SOURCES ${TX_R52_BASE_SOURCES})
endif()
target_sources(${PROJECT_NAME} PRIVATE ${TX_PORT_SOURCES})
target_include_directories(${PROJECT_NAME}
SYSTEM
PUBLIC
${TX_PORT_PATH}/inc
)
else()
add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/${TX_PORT_DIR}/${TX_ARCH_DIR}/${THREADX_TOOLCHAIN})
add_subdirectory(${TX_PORT_PATH})
endif()

# Pick up the common stuff
add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/${TX_COMMON_DIR})
if(THREADX_MODULE_MANAGER)
add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/common_modules/module_manager)
endif()

# Define the FreeRTOS adaptation layer
add_library(freertos-threadx EXCLUDE_FROM_ALL)
Expand Down Expand Up @@ -118,6 +174,9 @@ target_compile_definitions(${PROJECT_NAME} PUBLIC "TX_INCLUDE_USER_DEFINE_FILE"
if(THREADX_SMP)
target_compile_definitions(${PROJECT_NAME} PUBLIC "TX_MPCORE" )
endif()
if(THREADX_MODULE_MANAGER)
target_compile_definitions(${PROJECT_NAME} PUBLIC "TXM_MODULE_MANAGER" )
endif()

# Optional: build for S-mode (Supervisor mode) instead of M-mode (Machine mode).
# Required when running after OpenSBI, e.g. booted from U-Boot.
Expand Down
11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,17 @@ Instruction for building the ThreadX as static library using Arm GNU Toolchain a
$ cmake --build ./build
```

To build ThreadX with module manager support, enable `THREADX_MODULE_MANAGER`:

```bash
$ cmake -Bbuild-mm -GNinja -DCMAKE_TOOLCHAIN_FILE=cmake/cortex_m4.cmake -DTHREADX_MODULE_MANAGER=ON .

$ cmake --build ./build-mm
```

When enabled, the `azrtos::threadx` target includes the module manager kernel sources and public include headers (`txm_module.h`) for downstream targets.


## Licensing

License terms for using Eclipse ThreadX are defined in the LICENSE.txt file of this repo. Please refer to this file for all definitive licensing information for all content, incl. the history of this repo.
Expand Down
47 changes: 47 additions & 0 deletions common_modules/module_manager/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# Copyright (c) 2026 Eclipse ThreadX contributors
# SPDX-License-Identifier: MIT

target_sources(${PROJECT_NAME}
PRIVATE
${CMAKE_CURRENT_LIST_DIR}/src/txm_module_manager_absolute_load.c
${CMAKE_CURRENT_LIST_DIR}/src/txm_module_manager_absolute_load_extended.c
${CMAKE_CURRENT_LIST_DIR}/src/txm_module_manager_application_request.c
${CMAKE_CURRENT_LIST_DIR}/src/txm_module_manager_callback_request.c
${CMAKE_CURRENT_LIST_DIR}/src/txm_module_manager_event_flags_notify_trampoline.c
${CMAKE_CURRENT_LIST_DIR}/src/txm_module_manager_file_load.c
${CMAKE_CURRENT_LIST_DIR}/src/txm_module_manager_in_place_load.c
${CMAKE_CURRENT_LIST_DIR}/src/txm_module_manager_initialize.c
${CMAKE_CURRENT_LIST_DIR}/src/txm_module_manager_internal_load.c
${CMAKE_CURRENT_LIST_DIR}/src/txm_module_manager_kernel_dispatch.c
${CMAKE_CURRENT_LIST_DIR}/src/txm_module_manager_maximum_module_priority_set.c
${CMAKE_CURRENT_LIST_DIR}/src/txm_module_manager_memory_load.c
${CMAKE_CURRENT_LIST_DIR}/src/txm_module_manager_object_allocate.c
${CMAKE_CURRENT_LIST_DIR}/src/txm_module_manager_object_deallocate.c
${CMAKE_CURRENT_LIST_DIR}/src/txm_module_manager_object_pointer_get.c
${CMAKE_CURRENT_LIST_DIR}/src/txm_module_manager_object_pointer_get_extended.c
${CMAKE_CURRENT_LIST_DIR}/src/txm_module_manager_object_pool_create.c
${CMAKE_CURRENT_LIST_DIR}/src/txm_module_manager_properties_get.c
${CMAKE_CURRENT_LIST_DIR}/src/txm_module_manager_queue_notify_trampoline.c
${CMAKE_CURRENT_LIST_DIR}/src/txm_module_manager_semaphore_notify_trampoline.c
${CMAKE_CURRENT_LIST_DIR}/src/txm_module_manager_start.c
${CMAKE_CURRENT_LIST_DIR}/src/txm_module_manager_stop.c
${CMAKE_CURRENT_LIST_DIR}/src/txm_module_manager_thread_create.c
${CMAKE_CURRENT_LIST_DIR}/src/txm_module_manager_thread_notify_trampoline.c
${CMAKE_CURRENT_LIST_DIR}/src/txm_module_manager_thread_reset.c
${CMAKE_CURRENT_LIST_DIR}/src/txm_module_manager_timer_notify_trampoline.c
${CMAKE_CURRENT_LIST_DIR}/src/txm_module_manager_unload.c
${CMAKE_CURRENT_LIST_DIR}/src/txm_module_manager_util.c
)

target_include_directories(${PROJECT_NAME}
SYSTEM
PUBLIC
${CMAKE_CURRENT_LIST_DIR}/inc
${CMAKE_CURRENT_LIST_DIR}/../inc
)

# Define consumer check demonstrating compilation against the module-manager API
add_library(threadx-module-manager-consumer-check OBJECT EXCLUDE_FROM_ALL
${CMAKE_CURRENT_LIST_DIR}/consumer_check.c
)
target_link_libraries(threadx-module-manager-consumer-check PRIVATE azrtos::threadx)
51 changes: 51 additions & 0 deletions common_modules/module_manager/consumer_check.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/***************************************************************************
* Copyright (c) 2026 Eclipse ThreadX contributors
*
* This program and the accompanying materials are made available under the
* terms of the MIT License which is available at
* https://opensource.org/licenses/MIT.
*
* SPDX-License-Identifier: MIT
**************************************************************************/

#include "tx_api.h"
#include "txm_module.h"

static TX_THREAD module_manager_thread;
static ULONG module_manager_stack[1024 / sizeof(ULONG)];
static UCHAR object_memory_pool[16384];
static UCHAR module_data_area[32768];
static TXM_MODULE_INSTANCE test_module;

static VOID test_fault_handler(TX_THREAD *thread, TXM_MODULE_INSTANCE *module)
{
(VOID) thread;
(VOID) module;
}

static VOID module_manager_entry(ULONG input)
{
(VOID) input;
txm_module_manager_initialize((VOID *) module_data_area, sizeof(module_data_area));
txm_module_manager_object_pool_create(object_memory_pool, sizeof(object_memory_pool));
txm_module_manager_memory_fault_notify(test_fault_handler);
txm_module_manager_maximum_module_priority_set(&test_module, 5);
txm_module_manager_start(&test_module);
txm_module_manager_stop(&test_module);
txm_module_manager_unload(&test_module);
}

VOID tx_application_define(VOID *first_unused_memory)
{
(VOID) first_unused_memory;
tx_thread_create(&module_manager_thread, "Module Manager",
module_manager_entry, 0,
module_manager_stack, sizeof(module_manager_stack),
1, 1, TX_NO_TIME_SLICE, TX_AUTO_START);
}

int main(void)
{
tx_kernel_enter();
return 0;
}