mirror of
https://github.com/eclipse-threadx/threadx.git
synced 2026-10-06 06:59:08 +08:00
master
16
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
990faf670d |
Enabled execution profiling for Cortex-R5 (#766)
The Cortex-R5 assembly guarded its execution-profile hooks with only the legacy TX_ENABLE_EXECUTION_CHANGE_NOTIFY symbol. The documented TX_EXECUTION_PROFILE_ENABLE configuration initialized profiling without recording thread or interrupt transitions. I made all AC5, AC6, GNU, Green Hills, and IAR hooks accept both symbols. I also extended the port consistency and GNU/LLVM feature checks to cover the current configuration. All 849 base assembly files and all 219 TX_EXECUTION_PROFILE_ENABLE files passed with GCC 14.2.1 and clang 22.1.0. A CMake/Ninja Cortex-R5 profile build emitted all seven expected hook relocations. Proprietary toolchains were not run. Assisted-by: Codex (GPT-5) <noreply@openai.com> |
||
|
|
8be4c45cce |
Compiled the module manager C sources, which no check had ever built (#689)
* Compiled the module manager C sources, which no check had ever built #672 corrected this script's assembly glob and brought the module ports into the count, but only their assembly. Their C stayed outside every check: 27 files of portable module manager under common_modules, plus the per-port code under ports_module/<core>/gnu/module_manager/src. By this script's own standard -- a port simply absent from the count reads as covered -- 293 files across nine Arm module ports were compiled by nothing, with either compiler. Each module port ships its own tx_port.h and txm_module_port.h carrying the control-block extensions the dispatch code needs, so a port is compiled against its own headers rather than the base port's. Two details the ports themselves dictate: An SMP port's control blocks come from common_smp. Pairing cortex_a35_smp with the single-core headers hid _tx_thread_smp_protect and _tx_thread_smp_unprotect behind implicit declarations and lost tx_thread_smp_core_executing from TX_THREAD, so fourteen files reported errors for a port that builds correctly. The TrustZone ports carry cmse_nonsecure_entry, which needs -mcmse to be honoured rather than ignored. tx_thread_secure_stack.c also carries GCC's optimize attribute, which clang does not implement; that divergence is suppressed by name, for a file GCC builds cleanly. All nine ports compile: 293 of 293. Verified that the stage fails as intended by injecting a defect into a throwaway worktree -- a defect in common_modules is reported under every port, one in a port's own source only under that port. Assisted-by: Claude Code (Opus 5) * Ran the module manager stage against the sources that reach it Three corrections to the new stage, all found by running it against dev rather than against the tree it was written on. The workflows did not trigger on common_modules. Both check_clang.yml and check_gcc.yml list ports_module but not common_modules, and the portable module manager under it is the larger half of what the stage compiles -- 28 of the 31 to 37 files each port builds, plus two include directories. A change there left the stage unrun, which is the same "absent from the count reads as covered" that the stage exists to close. Both lists gain common_modules, and they stay identical to each other as the comment in each asks. A deliberate deprecation notice read as a build failure. Since this PR was opened, txm_module_manager_absolute_load.c gained a #pragma message steering callers to the extended entry point. The stage treats any compiler output as a failure, so that one notice failed every port: nine failures on a tree where nothing is wrong. Pragma messages are now waived for the stage, because a notice to callers is not a defect in the file that carries it. That failure also printed nothing. Both C stages report by grepping the output for "error:", so a diagnostic that is not an error produced a bare FAIL line with no reason under it, and the only way to learn the reason was to reproduce the compile by hand. Both stages now fall back to showing what the compiler actually said. The TrustZone attribute waiver is narrowed to the one file that needs it. tx_thread_secure_stack.c carries GCC's optimize attribute, which clang does not implement; it is the only file among the 300-odd this stage compiles that does. Waiving the warning for the whole port would have swallowed a stray unknown attribute anywhere else in it. Verified with the same toolchain CI uses, ATfE 22.1.0: the full script passes, and every port compiles every file. cortex_a35 31/31 cortex_a35_smp 31/31 cortex_a7 34/34 cortex_m0+ 33/33 cortex_m23 37/37 cortex_m3 33/33 cortex_m33 37/37 cortex_m4 33/33 cortex_m7 33/33 The counts are each one higher than this PR first reported, because txm_module_manager_absolute_load_extended.c has landed since. The stage picked it up with no edit, which is what globbing the directories was for. Assisted-by: Claude Code (Opus 5) <noreply@anthropic.com> --------- Co-authored-by: r <r@r> |
||
|
|
9c32abb17d |
Assembled the module ports, which no check had ever compiled (#672)
scripts/check_clang.sh globbed ports_module/*/gnu/src, which does not exist --
the module ports keep their assembly in module_manager/src. The [ -d ] guard
skipped it in silence, so 116 assembly files across nine Arm module ports were
assembled by no check, with either compiler, in the script whose own comments
state three times that "a port that is simply absent from the count reads as
covered". Stage 1 goes from 724 of 724 to 840 of 840; the feature-macro stage
had the same gap and goes from 412 files to 469.
Correcting the path exposed five defects, and only one of them was a build
failure. The other four assembled cleanly and did the wrong thing, because GAS
runs the C preprocessor on .S and not on .s:
ports_smp/cortex_a7_smp/gnu/src/tx_thread_smp_unprotect.s, the only .s in a
directory of twenty-one .S, ignored all four of its own feature macros. It
wrote the caller's LR into the protection structure on every unprotect -- a
store guarded by TX_MPCORE_DEBUG_ENABLE -- sent an unconditional SEV, and
returned through both BX lr and MOV pc, lr. Its cortex_a5_smp and
cortex_a9_smp siblings are .S.
ports_module/cortex_m33/.../tx_thread_stack_build.s emitted both arms of an
#ifdef TX_SINGLE_MODE_SECURE, so the non-secure LR value overwrote the secure
one and the secure build got the wrong frame.
ports_module/cortex_m23/.../tx_thread_context_{save,restore}.S carried the
POP {r0, lr} that check_clang.sh's own comment describes as the reason the
feature-macro stage exists. The 16-bit Thumb POP takes r0-r7 and pc only.
The identical fix already sits in ports/cortex_m23/gnu/src; the module copy
never got it because nothing scanned it.
ports_module/cortex_m23/.../tx_thread_secure_stack_initialize.S used MOV
rather than MOVS for an 8-bit immediate, latent behind TX_SINGLE_MODE_SECURE.
Both siblings in the same directory already use MOVS.
ports_module/cortex_a7/gnu/module_manager/src is the one that failed to
assemble, on GCC 14.3 as well as on LLVM: #define SYS_MODE was never
expanded, so #SYS_MODE reached the assembler as an undefined symbol.
Twenty-nine .s files under gnu trees are renamed to .S. Every one of them is
already named .S by the build scripts that compile it, so this repairs those
scripts rather than churning them -- ports_module/cortex_a7's build_threadx.bat
names all eighteen with a capital S, and works today only on a case-insensitive
filesystem. Renaming rather than converting the #defines to GNU assignments is
what fixes the #ifdef blocks as well as the constants; the assignments would
have fixed two files and left twenty-seven silently ignoring their macros.
Files with no preprocessor directives are left as .s: they are not broken, and
check_ports.sh gains a check that keeps them that way. Only the gnu trees are
checked there -- the IAR, Arm Compiler 5 and Keil assemblers preprocess .s
themselves, and about three hundred files in this repository rely on that.
Verified with both toolchains on the same tree: 840 of 840 assembled by
ATfE 22.1.0 and by arm-gnu-toolchain 14.3.rel1, all five stages of
check_clang.sh green, and check_ports.sh green including the reproducibility
check. The new check was shown to fail by planting a copy of the file it was
written for.
No regression test accompanies this. The assembly it covers is executed by no
host test, and the check itself going from 724 files to 840 is the coverage
AGENTS.md asks for -- together with the new check_ports.sh section, which is
what stops the class recurring.
Assisted-by: Claude Code (Opus 5) <noreply@anthropic.com>
|
||
|
|
090f8edc56 |
Added Cortex-M52 (Armv8.1-M) port (#519)
* ports: add Cortex-M52 (Armv8.1-M) port support Add ThreadX port for Cortex-M52, supporting three toolchains: - GNU (GCC) - AC6 (Arm Compiler 6) - IAR Cortex-M52 is an Armv8.1-M Mainline processor sharing the same architecture profile as Cortex-M55 and Cortex-M85. The port is functionally identical to the existing Cortex-M85 port. * ports: update cortex_m52 port copy script,using it update content -Add cortex_m52 in threadx/scriprts/copy_armv8m.sh -Using updated copy_armv8m.sh to generate new cortex_m52 port content * Regenerated the Cortex-M52 port against dev and wired it into the checks The port was generated from ports_arch/ARMv8-M as it stood on master, which has since moved on. Rebasing onto dev and running scripts/copy_armv8_m.sh again brings the twelve stale files into line, which is the point of generating them: the core picks up every ARMv8-M fix made since without anyone porting it by hand. Among what it picks up: "MOV r0, 0" becomes "MOV r0, #0" in the schedule and system-return paths, the non-canonical immediate form that GNU as tolerates and LLVM's assembler rejects; and gnu/src/tx_initialize_low_level.S goes away, since the shared source no longer has it. Two integration points exist only on dev, so the original change could not have included them. cmake/cortex_m52.cmake, so the port can be selected the documented way. Every other Cortex-M core has one. It uses the hard float ABI, as Cortex-M55 and Cortex-M85 do. An entry in scripts/check_clang.sh, likewise with -mfloat-abi=hard. That flag is not decoration: -mcpu=cortex-m52 implies Helium, and building it soft-float ends in "multilib configuration error: No library available for MVE with soft-float ABI" on every file, which reads as a broken port rather than a missing flag. Verified after regenerating: scripts/copy_armv8_m.sh is a no-op, so the tree matches its source; all 14 assembly sources and 188 C sources compile for cortex-m52 with Arm Toolchain for Embedded 22.1.0. Note for anyone building with GNU tools: arm-none-eabi-gcc 13.2.1 rejects -mcpu=cortex-m52 outright. Support arrives in GCC 14. --------- Co-authored-by: Frédéric Desbiens <frederic.desbiens@eclipse-foundation.org> Assisted-by: Claude Code (Opus 5) <noreply@anthropic.com> |
||
|
|
358e7a9ea5 |
Stopped the remaining example scripts naming archives that were deleted (#620)
#618 fixed the arm9 and arm11 shell scripts, but not their .bat counterparts, and did not look at cortex_r4 and cortex_r5 at all. An audit of every build script against the files actually present in its directory found the rest. The .bat scripts for arm9, arm11, cortex_r4 and cortex_r5 still linked libc.a, libgcc.a and, for arm11, libnosys.a from their own example_build directories, and the cortex_r4 and cortex_r5 shell scripts did too. Those archives went in 6.1.10 under "Removal of unneeded files", so on Windows all four examples failed exactly as the shell versions did before #618, and on Linux the two R-profile ones still did. Link through the compiler driver, as the other examples have since #594. This does not make the examples link, and the change stops there deliberately. All four now fail the same way, undefined reference to `_fini' because their linker scripts define the .init and .fini sections but not the _init and _fini symbols, which live in crti.o and crtn.o and are omitted by -nostartfiles. Reviving four very old cores is separate work. Correct the comment on EXAMPLES_EXPECTED_TO_FAIL again. It had cortex_r4 and cortex_r5 failing for want of newlib multilib variants; they do not. All four share the single cause above, and the multilib explanation was wrong for the R-profile pair just as it was for arm9 and arm11. Verified by running each shell script: cortex_r4 and cortex_r5 fail on _fini rather than on missing files, matching arm9 and arm11. The .bat changes mirror link lines proven that way in the same directories; they cannot be run here. Three scripts are left alone and reported instead, because a blind edit could not be verified: ports_module/cortex_m3 and cortex_m4 have Windows-only .bat scripts that also name sources which are absent or differ in case, and ports_smp/mips32_interaptiv_smp needs a MIPS toolchain. Assisted-by: Claude Code (Opus 5) <noreply@anthropic.com> |
||
|
|
20d4b977f2 |
Removed generated build output and per-user IDE state, and fixed two stale link lines (#618)
* Removed generated build output and stopped two scripts naming deleted archives Three kinds of file in the tree are produced by a build rather than written by hand, and one pair of scripts still links archives that were deleted years ago. Keil writes ThreadX_Library.plg on every build; the two committed copies are HTML build logs from someone's machine. Code Composer generates the makefiles under ports/c667x/ccs/example_build/tx/Release from the project files beside them, so makefile, objects.mk, sources.mk, subdir_rules.mk, subdir_vars.mk and ccsObjs.opt are all regenerated output. The arm9 and arm11 sample builds link libc.a, libgcc.a and, for arm11, libnosys.a from their own example_build directories. Those archives were removed in 6.1.10 under "Removal of unneeded files", and libnosys.a in #594, but the link lines were never updated, so both examples fail immediately with arm-none-eabi-ld: cannot find libc.a: No such file or directory Link through the compiler driver instead, the shape every other example in the tree uses since #594: the driver supplies libc and libgcc, and SYSCALL_LIB is already defined in both scripts. That does not make either example link, and the fix stops short of that on purpose. With the archives no longer named, both now fail on undefined reference to `_fini' because their linker scripts define the .init and .fini sections but not the _init and _fini symbols, which live in crti.o and crtn.o and are omitted by -nostartfiles. Making those two old cores build is a separate question from removing a stale reference, so they stay in EXAMPLES_EXPECTED_TO_FAIL, with the comment there corrected: it blamed newlib multilib packaging, which is true of cortex_r4 and cortex_r5 but was never the reason for arm9 and arm11. Reproduced throughout with arm-none-eabi-gcc 13.2.1. Assisted-by: Claude Code (Opus 5) <noreply@anthropic.com> * Removed the Keil per-user state files and ignored them Every Keil project in the tree carried a second file holding per-user state: 25 .uvoptx beside the 25 .uvprojx, 9 .uvopt beside the 9 .uvproj, and 3 .uvgui multi-project workspace files. uVision rewrites all of them whenever a project is opened, so they record whoever last had it open rather than anything about the port: debugger selection, breakpoints, watch windows, window geometry. Nothing in the tree references them, and every affected directory keeps its .uvprojx or .uvproj, which is the file that actually describes the project. Add ignore rules so they do not come back the next time someone opens a project and commits. 1.4 MB across 37 files. Assisted-by: Claude Code (Opus 5) <noreply@anthropic.com> |
||
|
|
c991c9e6ae |
Added TX_ENABLE_FIQ_SUPPORT to the feature-macro assembly stage (#610)
#608 assembled the code behind TX_ENABLE_VFP_SUPPORT, TX_LOW_POWER and TX_ENABLE_EXECUTION_CHANGE_NOTIFY, and missed TX_ENABLE_FIQ_SUPPORT, which guards assembly in 145 files across the A and R profile ports. All 145 assemble today, so this adds no fix, only the regression protection the other three already have. Also recorded why TX_ENABLE_IRQ_NESTING and TX_ENABLE_FIQ_NESTING are not in the list, since their absence otherwise looks like the same oversight. They guard no assembly in the trees this script walks: the nesting start and end routines are separate files compiled unconditionally, and the macros only feed the TX_PORT_SPECIFIC_BUILD_OPTIONS bitfield in tx_port.h. Adding them would assemble nothing new while implying coverage that does not exist. Verified with Arm Toolchain for Embedded 22.1.0: 711 of 711 assembly sources, then 37 of 37 VFP, 145 of 145 FIQ, 8 of 8 TX_LOW_POWER and 218 of 218 TX_ENABLE_EXECUTION_CHANGE_NOTIFY. Assisted-by: Claude Code (Opus 5) <noreply@anthropic.com> |
||
|
|
acdc02b2fc |
Assembled the code behind feature macros, and fixed the POP it found (#608)
scripts/check_clang.sh assembled every source with default flags, so the
preprocessor discarded each #ifdef block before the assembler saw it. Nothing in
the tree had ever assembled a guarded path. That covers the VFP context save and
restore in ten ports, and 218 files carrying TX_LOW_POWER or
TX_ENABLE_EXECUTION_CHANGE_NOTIFY.
Turning those on found a defect. The Cortex-M0 and Cortex-M23 execution-profile
paths bracket their call with
PUSH {r0, lr}
BL _tx_execution_isr_enter
POP {r0, lr}
and the last of those is invalid on Armv6-M and Armv8-M Baseline, where the
16-bit Thumb POP takes r0-r7 and pc and nothing else. GNU rejects it as well --
"cannot honor width suffix" -- so TX_ENABLE_EXECUTION_CHANGE_NOTIFY and
TX_EXECUTION_PROFILE_ENABLE have never been buildable on either port with either
toolchain. Four files, all the same shape.
The fix pops into a scratch register and moves it, MOV to a high register being
permitted where POP is not. r1 is free: the BL may clobber r0-r3, which is the
reason r0 is saved in the first place. Disassembling the result gives
push {r0, lr} / bl / pop {r0, r1} / mov lr, r1 / bx lr, one 16-bit instruction
more than before and otherwise the same.
Two findings that were not defects, recorded in the script so they are not
rediscovered:
Cortex-R4 needs an -mfpu to assemble its VFP path, because its FPU is an option
rather than part of the core. GNU fails identically without one, so this is a
flags requirement and not a toolchain divergence.
The A profile ports must not be given one. Adding -mfpu=vfpv3-d16 uniformly broke
28 files with "register expected", because those ports save D16-D31 and a -d16
FPU does not have those registers. Their defaults were already right.
The new stage runs under --asm-only as well, needing no target C library, and
reports 37 of 37 VFP files, 8 of 8 TX_LOW_POWER and 218 of 218
TX_ENABLE_EXECUTION_CHANGE_NOTIFY. Restoring the POP for one run makes it fail
with 217 of 218 and name the file and the error, so the stage is not vacuous.
The other four stages are unchanged: 711 of 711 assembled, 185 of 185 common C
sources for each of nine cores, 42 of 42 script-driven examples and 5 of 5 CMake
images.
The fixed code is verified to assemble with both toolchains and to encode as
intended. It is not verified running: there is no Cortex-M0 or Cortex-M23 model
here, and these are context save and restore paths, so that gap is worth stating.
Assisted-by: Claude Code (Opus 5) <noreply@anthropic.com>
|
||
|
|
b0ad67bae9 |
Brought the Cortex-R52 examples under the LLVM check, and fixed two blockers (#604)
#600 added a line reporting which example builds the LLVM check passes over, and cortex_r52 was on it: its examples are driven by CMake rather than by a build_threadx.sh pair, so the linking stage never touched them. Covering them turned up two reasons they could not have been built with anything but GNU. .arch armv8-r has no portable spelling. GNU as accepts it, and LLVM's integrated assembler rejects every variant -- armv8-r, armv8r, armv8-r+crc -- with "Unknown Arch: armv8-r". There is nothing to substitute, so the directive is gone from entry.S and tx_initialize_low_level.S; -mcpu=cortex-r52 already selects the architecture, both toolchain files pass it, and the directive only restated it. Worth noting where this hid: the assembly stage walks ports/*/gnu/src, so example assembly had never been assembled by LLVM at all. -Wl,--no-warn-rwx-segments is GNU ld only, added in binutils 2.39. ld.lld does not warn about RWX segments and rejects the flag outright, failing the link with "unknown argument". It is now selected on CMAKE_C_COMPILER_ID rather than spelled into all six targets, and the reason it exists at all -- a bare-metal image has one flat DRAM region and leaves access control to the MPU -- moves to the one place that sets it. cmake/cortex_r52_clang.cmake is the toolchain file. It names the tools as found on PATH, which is what CI uses, then pins $HOME/toolchains if that directory exists, mirroring how cortex_r52.cmake pins the GNU toolchain and for the same reason. Falling back rather than requiring the pinned path keeps the file usable on a machine that keeps clang elsewhere. THREADX_TOOLCHAIN stays "gnu": there is no clang port directory, this builds the gnu sources with a different compiler, which is what the whole check does for every other Arm port. check_clang.sh gains a fourth stage for CMake-driven examples, and no longer reports cortex_r52 as a gap. It reads the image list out of the generated ninja graph rather than repeating it, so adding a target cannot escape the check, and filters out the cmake_object_order_depends_target_* phonies -- counting those reported ten images where there are five. Verified with Arm Toolchain for Embedded 22.1.0, the version the workflow pins. All five images link, and all five then run and pass on FVP_BaseR_AEMv8R: boot_check, demo_m2, demo_m3, demo_threadx and demo_mpu. That is a step beyond the AArch64 examples, which are link-verified only. The full check reports 711 of 711 assembly sources, 185 of 185 common C sources for each of nine cores, 42 of 42 script-driven examples and 5 of 5 CMake images, leaving only cortex_a5_smp, cortex_a7_smp and cortex_a9_smp listed as having no driver. GNU is unaffected: the same five images build with no warnings and the FVP test suite passes 5 of 5. Assisted-by: Claude Code (Opus 5) <noreply@anthropic.com> |
||
|
|
8031d8b9bb |
Enrolled the Cortex-R52 port in the LLVM C check and exposed the skipped examples (#600)
Two gaps in check_clang.sh, both of which made the Cortex-R52 port look better covered than it was. C_CORES gains cortex_r52. That list is described as one core per architecture profile, and Armv8-R AArch32 is a profile rather than a variant of Armv7-R: the port is written by hand instead of generated from ports_arch, so cortex_r5 does not stand in for its tx_port.h. The assembly was already covered, since #593 added the PORT_TARGET entry, but the common C sources had never been compiled against that header. The example stage skipped any directory lacking both driver scripts, and did so in silence. A port absent from the count reads as covered, which is how the two CMake based example builds under ports/cortex_r52 looked like part of the total while never being built. The stage now reports what it passed over, in the two distinct cases that exist. The comment above EXAMPLES_EXPECTED_TO_FAIL already asks for gaps to stay visible; this makes the code agree with it. Four Cortex-M ports turn out to carry build_threadx.sh with no build_threadx_sample.sh, so they were skipped despite having a driver: cortex_m23, cortex_m33, cortex_m55 and cortex_m85. Reported, not fixed. Whether those want a sample script is a separate question. The expected-to-fail test now runs before the Arm test rather than after. arm9 and arm11 are on that list but carry no PORT_TARGET entry, so testing for Arm first dropped them from the report entirely, reintroducing the same silence for two ports that were already being named. Verified with Arm Toolchain for Embedded 22.1.0, the version CI pins: 711 of 711 assembly sources, 185 of 185 common C sources for each of the nine cores including cortex_r52, and 38 of 38 example builds linking, so the built set is unchanged by this commit. The remaining driverless ports report as cortex_r52, cortex_a5_smp, cortex_a7_smp and cortex_a9_smp, the three A profile SMP ports having no example scripts and the R52 examples being driven by CMake. --help still frames the intended lines, since the additions sit below the range it selects by number. Assisted-by: Claude Code (Opus 5) <noreply@anthropic.com> |
||
|
|
13722fe702 |
Repaired the garbled description at the top of check_clang.sh (#598)
The comment block describing what the script does was left half-rewritten when the example link stage was added to it: one sentence ends mid-clause and the word "profile" appears twice, once as the tail of a sentence that was meant to be replaced. Say the three stages plainly instead, and keep the point the truncated sentence was making, that only the linking stage needs a target C library. This block is what --help prints, so the damage was user visible. Comment only; no behaviour change. Verified that --help still frames the intended lines, since it selects them by number. Assisted-by: Claude Code (Opus 5) <noreply@anthropic.com> |
||
|
|
51ca412b36 |
Added build scripts for the AArch64 examples, which had none (#597)
The AArch64 examples could only be built through the Arm Development Studio project files beside them. There was no script, so nothing in CI or on a developer's machine could build them, and the sources they need were never named anywhere: vectors.S, v8_aarch64.S and v8_utils.S were present but unreferenced, which is why a hand written link failed on GetCPUID, GetAffinity, InvalidateUDCaches and ZeroBlock. Those four are defined in v8_aarch64.S and v8_utils.S, in the tree all along. Add one pair of scripts, in ports_arch so every AArch64 port receives them. Both derive the -mcpu value and the kernel source directory from the port directory they sit in, so a single pair serves the twelve ThreadX ports and the twelve SMP ports, the latter building against common_smp and picking up the C sources those ports carry alongside the assembly. TOOLCHAIN=atfe selects Arm Toolchain for Embedded in place of the GNU toolchain, as it does for the ARMv7 example scripts. One symbol genuinely had no definition. startup.S calls initialise_monitor_handles to open the standard file handles over a debugger connection; the GNU toolchain provides it in libgloss through --specs=rdimon.specs, while picolibc has no equivalent and neither does the LLVM toolchain's semihosting library. semihost_stub.S supplies a weak no-op, linked for that toolchain only, so a real definition always wins. Extend scripts/check_clang.sh to cover ports_smp as well as ports, since the example builds now exist there too. Verified by building every AArch64 example with Arm Toolchain for Embedded: twelve ThreadX ports at 314,744 to 315,256 bytes of text and twelve SMP ports at 325,304 to 325,880. scripts/check_clang.sh now reports 35 of 35 example builds linking with none failing, the twenty-four new ones plus the eleven that already built. The images have not been executed: the sample targets the Base platform peripheral addresses, which the available emulator does not provide. Cortex-A34, and the Cortex-A34 and A78 SMP ports, are left out. They are not in the generator's core list, so they receive nothing from ports_arch and cannot be checked for reproducibility either. Bringing them in rewrites 114 files in those three directories, which deserves its own change. Assisted-by: Claude Code (Opus 5) <noreply@anthropic.com> |
||
|
|
08eff8061c |
Made the Cortex-A12, A15 and A17 examples link with an LLVM toolchain (#596)
Those three sample scripts compiled crt0.S and reset.S but named neither on the link line, and omitted -nostartfiles, so the toolchain was also free to link its own startup. Under GNU that produced a working image; under an LLVM toolchain picolibc's crt0 was pulled in and wanted __data_start, __data_source, __data_size, __bss_size, __stack, __tls_base and __arm32_tls_tcb_offset, none of which the linker script defines. Defining picolibc's contract in the shared linker script was tried first and abandoned: it reaches into ABI constants that cannot be verified here, and it is unnecessary, because the in-tree crt0.S is already a complete startup for this script. It sets up the stack and zeroes BSS between __bss_start__ and __bss_end__, and .data carries no AT() so there is nothing to copy. So the three scripts now pass -nostartfiles and name crt0.o and reset.o, which is what the four sibling A profile cores already do and what these scripts were evidently compiling those files for. Both the old and the new GNU images contain the in-tree startup, __vectors from reset.S and _mainCRTStartup from crt0.S, so the startup was already being used through implicit startup file resolution rather than an explicit operand. How that resolution happened without the objects being named is not accounted for here, which is itself the argument for naming them: the same implicit behaviour does not hold across toolchains, and that is why the LLVM link failed. Add a readme to each of the three example directories. Their tx_initialize_low_level.S is the generic ARMv7-A skeleton, 300 lines and identical across all three, with no interrupt controller programming, no timer and no vector table installation, where the A5, A7, A8 and A9 examples have all three and ship the matching Versatile Express support files. These three therefore demonstrate that the port builds; they will not receive a timer tick. Nothing in the tree said so, which invites the assumption that they are equivalent. Verified with both toolchains for all three cores. GNU links at 41,276 bytes of text, down from 41,768 because the unused toolchain startup is no longer included, and Arm Toolchain for Embedded links at 37,982 where it previously could not link at all. The resulting image is structurally sound: entry at _start, __vectors at address zero, and a BSS range in RAM. It has not been executed. scripts/check_clang.sh now links eleven of eleven example builds. Assisted-by: Claude Code (Opus 5) <noreply@anthropic.com> |
||
|
|
a8aebc5206 |
Completed the Cortex-M0 barriers and made its example build with both toolchains (#595)
Two unrelated Cortex-M0 gaps, both left over from earlier work. The memory barriers from #523 reached the Cortex-M0 gnu port but not its ac6 or iar siblings, in either the inline system return in tx_port.h or the assembly routine. Both take the same GNU or IAR code path, and iar already carried the entry barrier, so the missing pieces were the entry pair for ac6 and the barrier after restoring the interrupt posture for both. All three tools now match. The Cortex-M0 example could not link with any toolchain. cortexm0_crt0.S references 23 linker script symbols and the script defined only 12 of them, so __text_start__, __text_end__, __text_load_start__, the rodata and fast section symbols, and the ctors and dtors load addresses were all unresolved. The Cortex-M4 script defines all 23, including a .fast section with no content whose symbols exist so that the startup copy is a no-op, and its comment says as much. The Cortex-M0 script is brought to that same shape. That left the example failing under LLVM only, on instructions that ARMv6-M can encode just one way. The file declared .code 16 but no syntax mode, so GNU as used the legacy divided syntax in which a plain add or sub sets the flags implicitly, while LLVM implements unified syntax only and rejected the non-flag-setting spelling. Declaring .syntax unified and writing movs, adds and subs makes both assemblers agree, and the encodings GNU produces are byte identical before and after, verified by disassembling both objects. The Cortex-M0 example now links with GNU at 22,520 bytes of text and with Arm Toolchain for Embedded at 22,866, so it comes off the list of examples not expected to link and scripts/check_clang.sh now links eight of eight. Assisted-by: Claude Code (Opus 5) <noreply@anthropic.com> |
||
|
|
f3ab36dacc |
Made the example builds work with LLVM, and fixed four that were broken on Linux (#594)
* Made the example builds work with LLVM, and fixed four that were broken on Linux The gnu example builds are the natural LLVM path: Arm Toolchain for Embedded is LLVM based, consumes GNU ld linker scripts, and needs none of the scatter files or Arm DS projects the ac6 examples carry. So rather than port the ac6 examples, teach the gnu scripts to drive either toolchain. Each script now selects the toolchain from a TOOLCHAIN variable that defaults to gnu, so every existing invocation behaves exactly as before. TOOLCHAIN=atfe switches the compiler, adds the target triple, passes the entry symbol through to the linker rather than to the driver, and links the toolchain's own semihosting library in place of --specs=nosys.specs, which is a GCC spec file mechanism with no LLVM equivalent. That last choice avoids adding a syscall stub source to every example. The scripts are parameterised rather than duplicated. Copies of build scripts would drift the first time one side was edited, which is the failure this repository has just spent several changes recovering from. Four sample scripts could not run on a case-sensitive filesystem at all. They compiled MP_PrivateTimer.s and V7.s while the files on disk are MP_PrivateTimer.S and v7.s, and the Cortex-A5 and A9 scripts named MP_GIC.s where the file is MP_GIC.S. The link lines named V7.o accordingly. Corrected to match the files, which is why the Cortex-A5, A7, A8 and A9 examples now build on Linux where before they could not. Extend scripts/check_clang.sh to link the example builds as well as compile the sources, since compiling proves the sources parse while only linking exercises entry symbols, linker scripts and the C library together. Eight examples are listed as not expected to link, each with its reason, so the gaps stay visible rather than being silently skipped. Five of them fail with the GNU toolchain too and are therefore not LLVM problems: the Cortex-M0 example's crt0 references __text_load_start__, __text_start__ and __text_end__, which its linker script never defines, while the Cortex-M4 script defines the equivalents; the arm9, arm11, Cortex-R4 and Cortex-R5 examples need newlib multilib variants that are not present in every GNU toolchain packaging. The Cortex-A12, A15 and A17 examples fail only with LLVM, because their link line omits -nostartfiles so the toolchain's own crt0 is linked and wants picolibc's __data_start, __data_source, __data_size and __bss_size, which their linker script does not define. Verified by building every example with both toolchains. Seven link with both: Cortex-A5, A7, A8, A9, M3, M4 and M7. The GNU results are unchanged where they worked before, and now also succeed for the four scripts with the case bug. Assisted-by: Claude Code (Opus 5) <noreply@anthropic.com> * Resolved the compiler path before running the example builds The example stage runs each build script from inside its own directory, so a relative path passed with --clang stopped resolving there and every example build failed instantly. Local runs passed an absolute path and did not show it; the CI job passes a path relative to the workspace root, which did. Resolve the compiler to an absolute path once, before any directory change, and print it so the toolchain in use is visible in the log. Assisted-by: Claude Code (Opus 5) <noreply@anthropic.com> * Parameterised the archiver as well, and stopped the check hiding failures The toolchain selection covered the compiler but not arm-none-eabi-ar, which the scripts invoke 628 times to assemble the library archive. A machine with an LLVM toolchain and no GNU one therefore could not build any example, which is exactly the situation in CI: the runner has no Arm GNU toolchain installed. Local runs had one, so this only appeared once the job ran. Select the archiver alongside the compiler, taking llvm-ar from beside clang in the toolchain. The four scripts that call arm-none-eabi-ld directly are left alone: they are arm9, arm11, Cortex-R4 and Cortex-R5, all already listed as not expected to link, and their invocations are specific to GNU ld in ways that parameterising would not resolve. The check reported "example build produced no image" and then filtered the log for lines containing "error", which hid the actual cause, since a missing tool reports "command not found" or "No such file or directory". It now prints the tail of the log. That filtering cost two CI round trips to diagnose something the first run already knew. Verified by shadowing arm-none-eabi-gcc, arm-none-eabi-ar, arm-none-eabi-ld and the aarch64 equivalents with stubs that fail loudly, then running the whole check: all 711 sources assemble, all eight profiles compile and all seven example builds link without any GNU tool being invoked. The GNU default path still produces an identical image. The diagnostics were confirmed by pointing the archiver at a name that does not exist and checking that the reason appears. Assisted-by: Claude Code (Opus 5) <noreply@anthropic.com> |
||
|
|
68eb205768 |
Made the Arm ports build with LLVM, and added a check that keeps them that way (#593)
The gnu ports are only ever built with GNU tooling, and GNU as accepts several non-canonical forms that LLVM's assembler rejects. Nothing noticed, because nothing built them with anything else. This matters beyond clang itself: Arm Toolchain for Embedded is LLVM based and is the successor to Arm Compiler 6, so these are the code paths ac6 users move onto. Seven files needed changing, none of which alters the emitted code: LDREX and STREX take no offset in A32 state; the #imm form is Thumb-2 only. GNU as drops the redundant zero, LLVM rejects it. Removed from the Cortex-A5, A7 and A9 SMP protect routines. ARMv8-M Baseline has no flag-preserving MOV immediate, so GNU as already emits MOVS. Writing MOVS in the two Cortex-M23 sources says what the assembler was doing anyway. One of them sits in a branch only compiled for the single mode secure configurations, which is why it had never surfaced. The Cortex-M0 schedule routine wrote LDR r0, =#0x10000000 with a stray hash, which its own sibling file already wrote correctly. The Cortex-M0 system return routine selected the numbered subsection .text 32, which makes LLVM place the constant pool beyond the range a Thumb-1 PC relative load can reach. Plain .text fixes it and GNU accepts either form. The reason is recorded in the file, since 32 files pair a numbered subsection with a literal pool load and the rest only escape because Thumb-2 and A32 have far more range. Add scripts/check_clang.sh, which assembles every Arm gnu port source and compiles the common C sources for one core per architecture profile, and a clang_check workflow that installs Arm Toolchain for Embedded and runs it. The toolchain version is pinned and checksum verified, for the same reason the runner image is pinned. The port directory to target mapping in that script is explicit rather than prefix matched. Prefix matching is what makes cortex_a5 also match cortex_a53 and cortex_a55, which are AArch64, and assembling those as ARM32 produces hundreds of misleading errors; that mistake cost real time while measuring this, so the reason is recorded next to the table. Verified with Arm Toolchain for Embedded 22.1.0: 711 of 711 assembly sources assemble and 185 of 185 C sources compile for all eight profiles, against 6 assembly failures before the change. arm-none-eabi-gcc still assembles all 315 ARM32 sources, so nothing regressed for GNU. The check was confirmed to fail when any one of the fixes is reverted. Assisted-by: Claude Code (Opus 5) <noreply@anthropic.com> |