summaryrefslogtreecommitdiff
path: root/CMakeLists.txt
AgeCommit message (Collapse)Author
2026-09-09Marked every published ThreadX include directory as SYSTEM so applications ↵Frédéric Desbiens
no longer get warnings from ThreadX headers (#713) * Marked every published ThreadX include directory as SYSTEM so applications no longer get warnings from ThreadX headers Commit 8c3c08f added the SYSTEM keyword to the target_include_directories call in common/CMakeLists.txt, but the same call in every port, in the SMP common directory's consumers, in the POSIX and FreeRTOS compatibility layers, and for the generated tx_user.h directory was left unchanged. A consumer building with a strict warning set therefore still saw diagnostics coming from tx_port.h and from the compatibility layer headers, which is exactly what the original change set out to avoid. Added the SYSTEM keyword to all of those calls so CMake emits -isystem rather than -I for every directory holding a ThreadX public header. The ARMv7-M, ARMv8-M, ARMv7-A and ARMv8-A architecture sources under ports_arch were updated alongside the ports they generate, keeping the two in step. Directories that are PRIVATE to an example or test build were left as they are, since nothing is published from them. Fixes #290 Assisted-by: Copilot (Opus 5) <[email protected]> * Stopped apt-get update being a gate it was never meant to be apt-get update fails if any configured repository serves a bad index, including ones this project never reads. The GitHub runner image carries Google's and Microsoft's apt repositories, and a Hash Sum mismatch from Google's, their CDN caught mid-publish with the index and the Release file eight hours apart, failed all three attempts and turned a run red over a browser nobody was installing. Made a failed update warn and carry on, leaving apt-get install as the gate. Nothing is weakened by that: the install still exits on a package it cannot find, so an unreachable archive still stops the script, one step later and naming the package it could not get, which is a better diagnostic than a hash mismatch in a repository nobody asked for. Disabling third-party sources before updating would keep the update strict, but this script also runs on a contributor's own machine, and rewriting someone's apt configuration to suit CI would be worse than tolerating a stale index for an archive we do not read. Assisted-by: Copilot (Opus 5) <[email protected]>
2026-08-16Added the POSIX compatibility layer to the CMake build, with regression ↵Frédéric Desbiens
tests (#626) * Added the POSIX compatibility layer to the CMake build Nothing in the repository built the POSIX layer. The FreeRTOS layer next to it has had a target since the CMake build was introduced, so the POSIX one was the odd one out, and 106 source files went unbuilt by any target, on any architecture. Add a posix-threadx target, following the FreeRTOS layer's shape: a static library, EXCLUDE_FROM_ALL so the default build is unchanged, linking threadx and publishing its own directory as a PUBLIC include path. The sources live in their own CMakeLists.txt rather than the top-level file, as common/ does, because there are 106 of them. The seven posix_*.c files in the same directory are a demo and standalone signal tests, each with its own entry point, so they stay out of the library. The layer does not suit every configuration, and the target is only offered where it can work: - Hosted simulation ports (linux, win32, win64) build against a C library that already provides errno.h, pthread.h and the rest. The layer replaces those. Its pthread.h even uses _PTHREAD_H, the same include guard as glibc's, so its declarations are skipped wholesale and the build fails on missing types. Neutralising that guard only exposes the real problem: 69 conflicting definitions in a single translation unit, for time_t, struct timespec, sigset_t, pthread_t, pthread_mutex_t, sem_t and more. Both the layer and the C library implement POSIX, and only one of them can define those names. The linux port also emulates threads by calling the C library's pthread_create and sem_wait, which the layer exports itself, so linking the two would divert the port into the layer that sits on top of it. - SMP builds. px_int.h declares _tx_thread_current_ptr as a plain pointer, which is a per-core array under SMP, and the layer tracks no current core. Building the layer for the first time exposed one portability defect worth fixing rather than working around. tx_posix.h defined ssize_t as INT, with a comment conceding it should come from <sys/types.h>. That is correct only where the C library agrees: on AArch64 newlib makes ssize_t 64 bits, and every translation unit that reached a library header failed to compile. Defer to the library when it has declared the type, keyed on the _*_DECLARED guards newlib uses, and do the same for mode_t, which had the same problem waiting. Where no library declaration exists the previous definitions still apply, so the 32-bit targets that did build are unaffected. Verified by building posix-threadx for arm9, arm11, cortex_m0, cortex_m3, cortex_m4, cortex_m7, cortex_m33, cortex_m55, cortex_m85, cortex_a7, cortex_a9, cortex_r4, cortex_r5, cortex_a34, cortex_a53 and cortex_a55 with arm-gnu-toolchain-14.3.rel1, and for risc-v32 and risc-v64 with riscv64-unknown-elf: 18 of 18, 106 objects each. cortex_a78 has no non-SMP port and fails to configure with or without this change. Linking the result against libthreadx.a leaves only tx_application_define, _tx_initialize_low_level, the optional execution profile hooks, and memset and strlen unresolved, all of which the application or its C library supplies. The default build still produces libthreadx.a and no POSIX library. Compiling is not the same as working, and on the 64-bit targets in that list it is not enough. The layer carries a message by putting the address of a private buffer into the queue, and ULONG is 32 bits on every port, so that address only fits when TX_64_BIT is defined. Without it px_mq_send.c truncates the pointer and px_mq_receive.c casts the truncated value back, which GCC reports as nothing worse than a -Wpointer-to-int-cast warning. Defining TX_64_BIT is not a remedy either: tx_api.h then reaches for the extension pointer macros, which need tx_thread_extension_ptr in the thread control block, and outside ports_smp and ports/linux no port declares it. So the target builds everywhere, but the message queues are only sound on the 32-bit ports. That is pre-existing, it is not made worse here, and it is left for a change of its own. Assisted-by: Claude Code (Opus 5) <[email protected]> * Added regression tests for the POSIX compatibility layer The POSIX layer had no tests. The seven posix_*.c programs shipped beside it are demos: they print nothing, report no result and end in infinite loops, so they tell a person watching a debugger something and an automated run nothing. Add a suite under test/posix, laid out like the FreeRTOS one and driven the same way, with scripts/build_posix.sh and scripts/test_posix.sh over a run.sh that takes the same arguments as its RISC-V counterpart. The tests run on emulated hardware because they have nowhere else to go. The layer replaces the C library's POSIX headers and exports the same symbols the linux port calls to emulate threads, so a host build is not available to it. The RISC-V QEMU harness that the ThreadX suite already uses is, and this suite reuses its BSP and testcontrol.c rather than growing copies of them. Three tests to start: - posix_mq_basic_test sends a message through a queue and checks the contents and priority survive the round trip. - posix_mq_send_abort_test covers the leak fixed in #624, by filling a queue, blocking a sender on it, aborting the wait and watching the queue's byte pool. Reverting the fix makes it fail on the pool check, so it measures what it claims to. - posix_pthread_basic_test covers pthread creation, a mutex, a semaphore handoff, pthread_self and collecting an exit value through pthread_join. The queue's pool is sized (mq_maxmsg + 1) * (mq_msgsize + 11), which leaves room for about one message beyond a full queue, so the abort test uses small messages and a shallow queue. With a larger message the first leaked buffer exhausts the pool, tx_byte_allocate fails, and the sender disappears into the endless loop in posix_internal_error() instead of reporting anything. Sizing it this way keeps the failure legible as a pool measurement rather than a timeout. riscv32 only, and the reason is the layer rather than the harness. The layer puts the address of a message buffer into the queue, ULONG is 32 bits on every port, and a 64-bit address only fits there when TX_64_BIT is defined. Defining it makes tx_api.h use the extension pointer macros, which need tx_thread_extension_ptr in the thread control block, and no port outside ports_smp and ports/linux declares it. Configuring for risc-v64 stops with that explanation rather than building something that would corrupt a pointer at runtime. Verified with riscv64-unknown-elf and qemu-system-riscv32: 3 tests across default_build, disable_notify_callbacks_build, stack_checking_build and trace_build, 12 of 12 passing. Assisted-by: Claude Code (Opus 5) <[email protected]>
2026-08-12Gave the gnu ports a CMake build, which most of them lacked (#607)Frédéric Desbiens
The project guidelines ask for CMake and Ninja, but only 15 of the 59 gnu port directories had a CMakeLists.txt. None of the 27 AArch64 ports had one, so the architecture whose examples were repaired over the last few changes still could not be built the way the project says to build it, and nothing in CI could compile it. Add a CMakeLists.txt to the 44 that lacked one. Three of them are templates in ports_arch, because 34 of the 44 are generated: the ARMv7-A and AArch64 source lists are uniform within each family, so one template per family serves every core in it and update.sh distributes it. The other 10 ports have no generator and get their own file. Add the toolchain files those ports select, following the shape of cmake/cortex_a9.cmake. AArch64 needs a base file of its own rather than a variant of arm-none-eabi.cmake: it has no -marm or -mthumb to choose between and no -mfloat-abi, and aarch64-none-elf-gcc rejects -mlong-calls outright, so that flag cannot be carried across. The tools are named without a path, unlike cmake/cortex_r52.cmake which pins one, because pinning 30 files to a single machine's directory layout is the problem the previous change removed from the launch configurations. Three toolchain files cover ports that already had a CMakeLists.txt but no way to select it: the Armv8-M mainline gnu ports, cortex_m33, cortex_m55 and cortex_m85. Without cmake/<arch>.cmake the documented invocation cannot reach them. The top level needed one fix. It derives the SMP port directory as <arch>_smp, but ports_smp/linux and ports_smp/win64 predate that convention and carry no suffix, so those two could never be configured. Fall back to the bare name when the suffixed directory is absent. The check only fires when the suffixed directory does not exist, so no port that already resolved changes behaviour, and ports_smp/win64's existing CMakeLists.txt becomes reachable too. Verified by configuring and building every one: 53 of 53 static libraries build with cmake -G Ninja, using Arm GNU Toolchain 14.3.Rel1 for both arm-none-eabi and aarch64-none-elf. That covers the 44 new ports plus the 9 that already worked, and includes ports_smp/linux, which failed before the fallback. scripts/check_ports.sh passes, so the three templates and their 34 generated copies agree. Six gnu ports are still outside the CMake build, all for want of a compiler rather than a CMakeLists.txt: rxv1, rxv2 and rxv3 need the Renesas RX GNU toolchain and mips32_interaptiv_smp needs a MIPS one, neither of which is available here, so writing toolchain files for them would mean shipping untested guesses. risc-v32 and risc-v64 already build through their own differently named toolchain files. Assisted-by: Claude Code (Opus 5) <[email protected]>
2026-08-08Added Cortex-R52 port with Armv8-R AEM FVP example build (#579)Frédéric Desbiens
Added a ThreadX port for Arm Cortex-R52 with the GNU toolchain Adds ports/cortex_r52/gnu together with a CMake build, an example build for the freely available Armv8-R AEM FVP, and an automated test suite. The port is EL2-aware by construction. Cortex-R52 always implements EL2 and resets into it, so the reset path configures EL2, installs both the EL2 and EL1 vector tables, and only then drops to EL1 to run the kernel. Keeping that structure from the start lets partitioning work reuse the boot path rather than replace it; TX_R52_BOOT_AT_EL1 skips the EL2 stage where a vendor monitor has already dropped privilege. This is also the first R-profile port in the tree with a working CMake build. cmake/cortex_a9.cmake exists but ports/cortex_a9/gnu/CMakeLists.txt is empty, so no A- or R-profile port could be built this way before. Contents: - Kernel port: 16 assembly sources plus tx_port.h, seeded from the Cortex-R5/GNU port. - Build: cmake/cortex_r52.cmake and the port CMakeLists.txt, with soft/hard float, VFP, FIQ and IRQ/FIQ nesting options. - Example BSP: EL2 to EL1 boot, GICv3, generic timer, PMSAv8-R MPU, semihosting and PL011 consoles. - Tests: six images registered with CTest, each judging itself and terminating the model. - tx_port_offset_check.c: compile-time assertions on the TX_THREAD offsets the assembly reaches by hard-coded displacement. This is the same defect class fixed for Cortex-R4/R5 in #578; nothing in the toolchain ties those literals to the C structure. Two facts were established by experiment rather than taken from documentation, and are recorded in the code and the readme because both are traps: - PRBAR.AP bit order is reversed relative to th AArch64 macro set: the low bit is read-only and the high bit grants EL0 access. Programming four disjoint regions, one per encoding, and attempting a privileged write to each gave 0b and 0b10 allowed. Using the AArch64 ordering as read-only and silently accept writes, because region coverage is still enforced: an unmapped address faults while a "read-only" region does not. - The generic timer PPI is INTID 30, recorded from ICC_IAR1 after enabling the whole PPI range 25-31, rather than assume Model behaviour that a silicon port must revisit: the FVP leaves CNTFRQ at zero with the system counter stopped, so the BSP programs both; CNTHCTL.PL1PCTEN, CNTHCTL.PL1PCEN and ICC_HSRE must be set at EL2 or EL1 accesses trap; and tx_thread_vfp_enable() sets only a per-thread software flag, so enabling the FPU hardware (CPACR, FPEXC.EN) is the board support package's responsibility, not the kernel's. The FVP reports MIDR 0x410FD0F0, an architecture envelope model rather than a Cortex-R52, so it validates architecture and not implementation. Nothing in the port is gated on MIDR. Changes outside ports/cortex_r52, three and all small: cmake/cortex_r52.cmake is a new toolchain file; CMakeLists.txt gains enable_testing() at the top level, without which add_test() in a subdirectory generat the root never references, so ctest reports no tests from the build root; and .gitignore covers build directories and __pycache__. Verification: all six images build warning-free a FVP_BaseR_AEMv8R in three configurations -- protection off, protection and caches on, and both together with hard-float VFP. Six build-option combinations build clean and pass the tick-and-preemption demo at run time. The tests assert behaviour rather than configuration, which is what caught the problems above: the cooperative demo asserts the order of execution, because counting alone cannot distinguish working context switches from one thread running to completion, and the MPU test provokes real faults, because reading SCTLR back only proves a bit was set. The 96-test regression suite is host-side and pas configurations on the Linux port. It is not cross-run here: it validates portable kernel logic, while the port-specific risk is the assembly, which the FVP images exercise. Structural coverage is therefore not claimed. Deliberate deviations: passing a string literal to tx_thread_create reports a discarded const qualifier from common/inc/tx_api. CHAR *; demo_threadx.c keeps the shipped sample's int main() so the demo body stays byte-identical to it; and the floating-point test compares exactly on purpose, since a tolerance would mask a restored wrong. Not included: modules support, split-mode SMP and support. The example targets the FVP only, and NXP S32Z280 bring-up is separate work; the readme flags what to re-verify there. Assisted-by: Claude Code (Opus 5) <[email protected]>
2026-05-29cmake: fixed THREADX_ARCH undefined when building as standalone library (#540)Frédéric Desbiens
CMake loads the toolchain file during the first project() call. Variables set in the toolchain (THREADX_ARCH, THREADX_TOOLCHAIN) were therefore not visible before project() was invoked. Commit 2c16114a moved project() after those checks to conditionally select LANGUAGES and CMAKE_TRY_COMPILE_TARGET_TYPE for Windows, which broke standalone builds that rely on the toolchain to supply THREADX_ARCH. Fixed by calling project(threadx LANGUAGES C) first so the toolchain is sourced, then checking THREADX_ARCH, then conditionally enabling ASM via enable_language(ASM) for non-Windows ports. The CMAKE_TRY_COMPILE_TARGET_TYPE override was removed from CMakeLists.txt because every toolchain file in cmake/ already sets it to STATIC_LIBRARY where needed. Co-authored-by: Copilot <[email protected]>
2026-05-26Added win64 ports of ThreadX and ThreadX SMP (#529)Frédéric Desbiens
Windows x64 port and regression suite This PR adds the Windows x64 (Win64) simulation port for both the standalone and SMP variants of ThreadX, along with the full CMake build and test infrastructure needed to run the regression suite on Windows. New ports Win64 standalone (ports/win64/vs_2022): self-contained Windows simulation port using Win32 threading primitives as virtual cores. Includes CMake integration, build/test scripts, and MSVC project files. Win64 SMP (ports/win64_smp/vs_2022): multi-core Windows simulation port. Supports up to 4 virtual cores backed by Windows host threads. Scheduler and timer improvements The initial port used coarse polling and synchronous SuspendThread/ResumeThread pairs throughout the scheduler hot path. Several rounds of optimization reduced the SMP regression suite runtime from ~150 s to ~78 s (-48%), with no regressions: - Replaced scheduler polling with an event-driven wake path; switched the simulated timer to one-shot rearming to eliminate catch-up ticks. - Skip SuspendThread when _tx_thread_preempt_disable != 0 (new suspension type 3) -- the primary optimization, yielding up to 7.9x speedup on preemption-heavy tests. - Skip SuspendThread when a thread is spinning on the Win32 critical section (suspension type 4), and fix a stale-TLS bug in _tx_win32_critical_section_obtain that could stamp mutex_access on the wrong virtual core. - Added a 2 ms scheduler event timeout (matching the Linux SMP port) to prevent stalls on any missed SetEvent. - Enabled high-resolution waitable timers (SetWaitableTimerEx) for accurate 100 Hz tick cadence. - Increased TX_WIN32_CONTENTION_PAUSE_COUNT from 64 to 256 to reduce SwitchToThread overhead under heavy CS contention. Build and test infrastructure - Hardened the Windows build wrapper (scripts/build_tx.ps1): invoke Ninja directly for Ninja build trees, fix timeout detection, add a default build timeout, and limit fallback replay to real timeout cases. - Added -Clean support to Windows test scripts to remove stale CTest state before each run. - Skip Visual Studio DevShell re-entry when the active MSVC environment already matches the requested architecture. - Fixed scripts/build_tx.sh (Linux) regression source generation: replaced brittle exact-string insertion with line-based matching so the interrupt dispatcher hook is inserted reliably for both simulator ports. Test suite updates - Introduced test/tx/regression/threadx_test_port.h with portable macros (TX_TEST_POINTER_WORD, TX_TEST_STORE_POINTER) for storing pointers in test arrays on 64-bit targets where ULONG remains 32-bit. - Adjusted pool-capacity and pointer-storage patterns in regression tests to use ALIGN_TYPE-sized slots, making the suite correct on 64-bit hosts. - Restored stricter event flag, sleep, and timer expectations now that port-level fixes make prior Windows accommodations unnecessary. - Tightened SMP watchdog and clean-build timeout defaults. Version metadata Updated Win32, Win64, and Win64 SMP port version strings to 6.5.1.202602. Co-authored-by: Copilot <[email protected]> Co-authored-by: Codex (gpt 5.5) <[email protected]>
2026-05-25Added RISC-V board Bananapi BPI-F3 (SpacemiT K1 SoC) BSP Support (#531)Akif Ejaz
* Add BananaPi BPI-F3 BSP support Add RISC-V supervisor support to the rv64/gnu port and provide a complete board support package for the BananaPi BPI-F3 (SpacemiT K1 SoC, X60 cores). Port changes (risc-v64/gnu): - Guard all CSR accesses with TX_RISCV_SMODE to select S-mode registers (sstatus/sepc/sie/sret) vs M-mode (mstatus/mepc/mie/mret) in context_save, context_restore, schedule, system_return, interrupt_control, and stack_build. - Add S-mode TX_INT_ENABLE/TX_DISABLE and inline TX_RESTORE macros to tx_port.h. - Add TX_RISCV_SMODE CMake option to CMakeLists.txt. BananaPi BPI-F3 BSP (example_build/bananapi-f3): - Boot flow: FSBL → OpenSBI (M-mode) → U-Boot (S-mode) → ThreadX - S-mode trap handler with context save/restore integration - SBI legacy ecall timer at 10 Hz (24 MHz timebase) - PLIC driver with S-mode context, stale-IRQ drain, and callbacks - PXA-compatible UART0 console (115200 8N1) - Linker script at 0x200000 load address Tested on risc-v board, BananaPi BPI-F3 hardware. Signed-off-by: Akif Ejaz <[email protected]> * Fixed S-mode context restore and PLIC spurious IRQ handling - tx_thread_context_restore.S (non-nested path): set SPIE(0x20) alongside SPP(0x100) so sret re-enables interrupts in the restored thread. - tx_thread_context_restore.S (both S-mode paths): use FS=Dirty (0x6000) instead of FS=Initial (0x2000) to match tx_thread_schedule.S and prevent FP register corruption across context switches. - plic.c (plic_irq_intr): return early when plic_claim() yields 0 (no pending interrupt) to avoid completing a spurious IRQ ID 0, which is undefined behavior per the PLIC spec. Co-authored-by: Copilot <[email protected]> --------- Signed-off-by: Akif Ejaz <[email protected]> Co-authored-by: Frédéric Desbiens <[email protected]> Co-authored-by: Copilot <[email protected]>
2026-04-15build: add conditional CMake support for ThreadX SMPFrédéric Desbiens
- Introduce THREADX_SMP option in root CMakeLists.txt. - Implement conditional source and port directory selection for SMP builds. - Add CMake support for common_smp and Cortex-A9 SMP port. - Fix linker flags in Cortex-A9 SMP sample build script. - Remove duplicate invalidateCaches_IS declarations in v7.h headers. Assisted-by: Gemini (Experimental)
2026-03-05Updated copyright headers and version number constants (#509)Frédéric Desbiens
* Updated version number constants * Removed revision history from all files * Added Eclipse ThreadX contributors' copyright header
2025-02-24Updated CMake minimal version to 3.13Frédéric Desbiens
2022-07-26Release 6.1.12v6.1.12_relYuxin Zhou
2021-10-14Release 6.1.9Yuxin Zhou
2021-07-28Release 6.1.8v6.1.8_relYuxin Zhou
2020-05-22Fix a typo. (#4)TiejunZhou
2020-05-14Added a zip cpack targetPProvost
2020-05-11Initial commitPProvost