Conversation
* refactor(stm32f767): restructure project to support scalable demos and default to threadx_basic * feat(stm32f767zi): refactored BSP and added NetX Duo Echo demo
… and primitives showcase (#45) * new file: STMicroelectronics/NUCLEO_F401RE/CMakeLists.txt new file: STMicroelectronics/NUCLEO_F401RE/README.md new file: STMicroelectronics/NUCLEO_F401RE/app/CMakeLists.txt new file: STMicroelectronics/NUCLEO_F401RE/app/common/board_init.c new file: STMicroelectronics/NUCLEO_F401RE/app/common/board_init.h new file: STMicroelectronics/NUCLEO_F401RE/app/common/console.c new file: STMicroelectronics/NUCLEO_F401RE/app/common/sntp_client.c new file: STMicroelectronics/NUCLEO_F401RE/app/common/startup/NUCLEO_F401RE.ld new file: STMicroelectronics/NUCLEO_F401RE/app/common/startup/startup_stm32f401xe.s new file: STMicroelectronics/NUCLEO_F401RE/app/common/startup/tx_initialize_low_level.S new file: STMicroelectronics/NUCLEO_F401RE/app/common/stm32cubef4/stm32f4xx_hal_msp.c new file: STMicroelectronics/NUCLEO_F401RE/app/starter/cloud_config.h new file: STMicroelectronics/NUCLEO_F401RE/app/starter/main.c new file: STMicroelectronics/NUCLEO_F401RE/cmake/FindCMSIS.cmake new file: STMicroelectronics/NUCLEO_F401RE/cmake/FindSTM32HAL.cmake new file: STMicroelectronics/NUCLEO_F401RE/cmake/arm-gcc-cortex-m4.cmake new file: STMicroelectronics/NUCLEO_F401RE/cmake/arm-gcc-cortex-toolchain.cmake new file: STMicroelectronics/NUCLEO_F401RE/cmake/utilities.cmake new file: STMicroelectronics/NUCLEO_F401RE/lib/CMakeLists.txt new file: STMicroelectronics/NUCLEO_F401RE/lib/nucleo_bsp/CMakeLists.txt new file: STMicroelectronics/NUCLEO_F401RE/lib/nucleo_bsp/nucleo_bsp.c new file: STMicroelectronics/NUCLEO_F401RE/lib/nucleo_bsp/nucleo_bsp.h new file: STMicroelectronics/NUCLEO_F401RE/lib/stm32cubef4/CMakeLists.txt new file: STMicroelectronics/NUCLEO_F401RE/lib/stm32cubef4/config/stm32f4xx_hal_conf.h * Cmake files populated, HAL library and boot code copied and modified * Startup files obtained from official repositories and adjusted to meet board specs and ThreadX requirements * Fixed build sequence * STM32F401RE: achieve first successful ThreadX hardware bring-up Booted ThreadX on NUCLEO-F401RE Validated scheduler operation Validated UART console output Validated LED thread Validated flashing and hardware execution * implement ThreadX board initialization and multi-threading demo for NUCLEO-F401RE (continued) * Fixed licensing, added documentation * added CMake build configuration for NUCLEO-F401RE board * implemented dynamic memory management, added monitor thread * added bytepools and demonstrations of threadx features such as mutex and event flags. Modified demo README file to reflect changes. * Implemented block pools to prevent fragmentation of memory. Added semaphore functionality and 1 hz applicaion timer. * Added missing licensing header to main.c * Fixed incomplete NUCLEO licensing headers --------- Co-authored-by: Ammar Okla <ammargawkla@gmail.com> Co-authored-by: Frédéric Desbiens <frederic.desbiens@eclipse-foundation.org> Co-authored-by: Codex <codex@openai.com>
Added an STM32F767ZI environmental station demo using ThreadX, FileX, NetX Duo, MQTT, and an HTS221 sensor with mock fallback. Included resilient telemetry queueing, local RAM-disk logging, DHCP/DNS handling, MQTT reconnection, and updated board support and documentation. --------- Signed-off-by: alieissa-commits <ali.eissa.dev@gmail.com> Co-authored-by: Frédéric Desbiens <frederic.desbiens@eclipse-foundation.org> Co-authored-by: Codex <codex@openai.com>
* Add Microchip PolarFire SoC target, reusable BSP framework, and Renode CI pipeline * Add dynamic runtime self-tests for _sbrk bounds, timer catch-up, and queue integrity * Refine timer catch-up test and add per-thread run counters * Initialize early mtvec, add deliberate timeout and trap testing hooks, and port collision fix * Separate synchronous trap dispatch from interrupt context save * feat(polarfire): Implement and dynamically verify PLIC Hart 1 configuration and MMUART1 interrupt routing * Fixed PLIC machine-mode context and made the Renode self-tests gate CI Addressed the outstanding review items on the PolarFire SoC target. PLIC: plic.h programmed context 2, which is the supervisor-mode context for u54_1 on PolarFire SoC; the machine-mode context for that hart is context 1. Writing the supervisor context is silently accepted by the PLIC but leaves the machine-mode enable bitmap clear, so MEIP never asserts and MMUART1 interrupts could not be delivered. Threshold/claim move to 0x0C201000/0x0C201004 and the enable word to 0x0C002088. The context and enable-word offsets are now derived from the source ID rather than hardcoded. Self-tests: run_startup_self_tests() printed "All startup verification tests PASSED!" unconditionally, and test_renode.py grepped for exactly that string, so a failing sub-test still produced a green build. Results now feed a failure counter that decides the summary line, and the harness fails on any "[-] FAIL:". Renode harness: the exit code considered only ticks and the alarm, discarding the self-test and PLIC-RX flags it computed. All four assertions now gate the result, and the harness injects a byte into MMUART1 so the PLIC path is actually exercised instead of only having its registers inspected. The timer catch-up self-test no longer writes mtime. That register is the platform-wide monotonic counter shared by every hart, and this demo is meant to be copied. Only the per-hart mtimecmp is staged into the past, with the expected result bracketed by mtime sampled either side of hwtimer_ack(). Also: - Hardened _sbrk() in templates/target, which is the copy-me template: bounds check against BSP_RAM_END, reject underflow and pointer overflow, return (void *)-1 with errno, and take ptrdiff_t so it stays correct on 64-bit. - Implemented __malloc_lock/__malloc_unlock instead of leaving them empty, so the newlib arena is genuinely serialised rather than only appearing to be. - Gave the tick source one owner: _tx_initialize_low_level calls hwtimer_init, board_init handles board peripherals, so board_init no longer runs twice. - Pinned Renode to 1.16.1 and checksum-verified both CI downloads. - Updated polarfire_demo.robot, which asserted on telemetry strings the demo no longer emits, and added an RX interrupt case. - Derived the demo sleep intervals from TX_TIMER_TICKS_PER_SECOND. - Corrected the architecture.md tree and normalised the licence URL to the form used in AGENTS.md. * Fixed the timer catch-up self-test to exercise pure arithmetic The previous self-test staged mtimecmp eight ticks behind by subtracting from mtime. Renode starts mtime near zero, so that subtraction underflowed to 2^64-79900 and the test failed itself in CI. The production clamp was never wrong; the test fed it a value real code cannot produce. Extracted the catch-up decision into hwtimer_next_cmp(), a pure function of the current comparand and mtime, and left hwtimer_ack() as a thin wrapper. The test now covers both branches with synthetic values and touches no CLINT register at all, which also removes the last reason for the demo to write timer state. Replaced the TX_TIMER_TICKS_PER_SECOND fallback in hwtimer.h with BSP_TICK_RATE_HZ in board_config.h. The BSP does not see the ThreadX headers, so that fallback silently applied whenever the two disagreed; main.c sees both and now carries a C99 compile-time check that they match. The Renode harness no longer stops at the first failing self-test, so a single failure reports the state of every other assertion instead of hiding it. * Made the Renode run deterministic so the PLIC interrupt is actually exercised The RX assertion added in the previous commit never fired in CI. Renode does not read its monitor from stdin (it logs "Monitor available in telnet mode on port 1234"), so the byte the harness wrote was silently discarded and the PLIC path still went untested. Added renode/polarfire_ci.resc, which steps through fixed virtual-time intervals with emulation RunFor, injects the byte itself via WriteChar, and quits. The run is reproducible and terminates on its own rather than depending on wall clock. It duplicates the machine setup instead of including polarfire_demo.resc because Renode expands $ORIGIN only in variable assignment, so an included script cannot be located relative to the file including it; both "include @$ORIGIN/..." and a bare relative include hang the process rather than reporting an error. polarfire_demo.resc is left free-running for interactive use. Verified locally against Renode 1.16.1, both directions: context 1 -> [Console RX] PLIC IRQ 91 handled: byte 'X' ... harness exit 0 context 2 -> no RX line harness exit 1 Both builds print an identical "[+] PASS: PLIC Hart 1 (IRQ 91 prio=1 en=0x08000000 thresh=0 mie=0x800)" self-test line, which is the point: register readback cannot separate a correct context from an incorrect one, and only a delivered interrupt can. Also added timeout-minutes to both CI jobs as a backstop, and corrected the target README, whose expected-output block still showed telemetry strings the demo stopped emitting. --------- Co-authored-by: Ammar Okla <ammargawkla@gmail.com> Co-authored-by: Frédéric Desbiens <frederic.desbiens@eclipse-foundation.org>
…50) * feat(nucleo): Relocate NUCLEO_F401RE into targets and migrate to generic BSP framework * Bounded the newlib heap to its linker reservation _sbrk() bounded the heap at BSP_RAM_END (0x20018000), the end of physical SRAM. On this target that is not a guard at all. NUCLEO_F401RE.ld lays RAM out as: _end 0x20001170 heap base _end + _Min_Heap_Size 0x20001370 intended heap ceiling __RAM_segment_used_end__ 0x20001770 ThreadX byte pool starts here byte pool end 0x20017000 _estack / BSP_RAM_END 0x20018000 so malloc() could grow the break through the reserved main stack, through the entire ThreadX byte pool holding every thread stack and the queue buffer, and into the live MSP, all while _sbrk() reported success. Only an allocation past the top of SRAM returned ENOMEM. The linker script now exports _heap_limit at the end of the heap reservation and _sbrk() bounds against that, which keeps the heap inside the 0x200 the script already set aside for it. Both bounds checks are also computed in uintptr_t rather than by forming an out-of-bounds pointer first, and the negative branch derives its magnitude without negating PTRDIFF_MIN. BSP_RAM_END keeps documenting the memory map but now carries a note against reusing it as a heap bound. All newlib syscall overrides move into newlib_stubs.c, which the application compiles directly. _write() and _read() previously sat in bsp_console.c inside libbsp.a, where the linker extracted them only because bsp_board.o happened to reference bsp_console_init(); breaking that incidental chain would have silently handed printf to the libnosys stubs, and CI only checks that the ELF exists. Console input stays board specific behind nucleo_console.h, since the shared <bsp/console.h> contract is write-only. The BSP library is renamed nucleo_bsp, matching polarfire_bsp and freeing the bare "bsp" target name. The AI Disclosure header on newlib_stubs.c records the Codex-assisted origin of the syscall shims moved in from console.c. That work was done by Frederic Desbiens while editing PR #45, not by the PR author; the squash-merge in 1bddd17 assigned git authorship to the contributor and its Co-authored-by trailers are the accurate record. * Restored console error handling and the AI disclosure headers bsp_console_init() dropped the return value of HAL_UART_Init(). The code it replaced routed the failure to Error_Handler(); the migration left the call bare, so a UART that failed to initialise booted on silently with no console. MISRA C:2012 Rule 17.7. The status is checked again and a failure now halts, matching the previous behaviour. The UART handle was a non-static global named UartHandle, but the extern declaration that used to live in board_init.h went away with that header, leaving an object with external linkage that nothing declared (Rule 8.4 and 8.7). It is now file-scope static console_uart. The redundant GPIOA and USART2 clock enables are gone as well: HAL_UART_MspInit() already owns that configuration, which is what "single UART owner" should mean. The const cast required by HAL_UART_Transmit() is documented as a Rule 11.8 deviation. bsp_board.c, bsp_led.c and bsp_console.c carry the AI Disclosure header required by AGENTS.md for new files. They derive from board_init.c, nucleo_bsp.c and console.c, each of which carried "Some portions generated by Codex (GPT-5)"; the rename dropped the disclosure while keeping most of the content, and git scores bsp_board.c as an 80% similarity rename. That Codex work was Frederic Desbiens', done while editing another contributor's PR under the AGENTS.md exception permitting edits to incoming PRs. It reached the tree through 1bddd17, a GitHub squash-merge of PR #45 whose git author is the PR author but whose trailers name the real participants: Co-authored-by: Ammar Okla <ammargawkla@gmail.com> Co-authored-by: Frederic Desbiens <frederic.desbiens@eclipse-foundation.org> Co-authored-by: Codex <codex@openai.com> The disclosure is therefore not a statement about this PR's author. * Pinned the ARM toolchain to GCC 14 and refreshed the target documentation The build-arm-nucleo job installed the distribution's gcc-arm-none-eabi, which is GCC 13.2 on ubuntu-24.04, so the compiler drifted with the runner image. AGENTS.md specifies GCC 14 and the sibling RISC-V job already pins xPack GCC 14.2.0 by URL; the ARM job now pins Arm GNU Toolchain 14.2.Rel1 the same way. The toolchain bundles its own newlib, so the separate newlib packages are no longer installed. CMAKE_C_STANDARD moves from 11 to 99 per the AGENTS.md C99 requirement. The target builds clean under both GCC 13.2.1 and the pinned GCC 14.2.1 with -Wall -Wshadow -Wdouble-promotion -Werror. README.md moved with git mv but still described the pre-migration layout: the build directory as STMicroelectronics/NUCLEO_F401RE, the HAL timebase overrides as living in board_init.c, and the BSP as lib/nucleo_bsp/. All three are corrected and the BSP entry now lists the four sources behind the generic interfaces. The Validation Record quoted 18244 B ROM and 5632 B RAM against a toolchain the CI pipeline does not use. Re-measured against the newly pinned GCC 14.2.1: 20120 B ROM and 6000 B RAM. The hardware verification checklist is left as the contributor recorded it. --------- Co-authored-by: Ammar Okla <ammargawkla@gmail.com> Co-authored-by: Frédéric Desbiens <frederic.desbiens@eclipse-foundation.org>
The ARM target had no runtime test. Its CI job checked only that the ELF existed, so the clock configuration, the TIM2 HAL timebase, the console and the heap bound were all unexercised. This brings it to parity with the PolarFire target, which gates CI on a headless Renode run. Renode ships no NUCLEO-F401RE board description, so renode/nucleo_f401re.repl derives one from the generic STM32F4 CPU platform and corrects Flash to 512 KB and SRAM to 96 KB. The generic platform is sized for the larger F407/F429 parts, and both the linker script's heap reservation and the _sbrk() bound depend on those limits being right. main.c gains seven startup self-tests that run before tx_kernel_enter(), so a failure is reported even when the scheduler never starts. They cover the _sbrk() allocate, release, underflow and over-limit paths, the invariant that the heap reservation ends at or below the ThreadX byte pool, the 84 MHz SystemCoreClock, and that TIM2 still ticks after HAL_RCC_ClockConfig() re-enters HAL_InitTick(). Test 4 is the regression guard for the heap bound fixed in #50. Requesting 32 KB fits inside the 96 KB SRAM but far exceeds the heap reservation. Reinstating the old end-of-SRAM bound was verified to fail the suite: newlib's first malloc() then took roughly 4 KB and put the break at 0x20002170, inside the ThreadX byte pool, which also broke self-tests 1 and 3. With the bound correct, _sbrk() refuses the oversized request, newlib retries smaller, and malloc(64) succeeds using 72 bytes of the 512-byte reservation - so the reservation is adequate and no heap growth is needed. scripts/test_renode.py drives nucleo_f401re_ci.resc, which advances a fixed span of virtual time and quits on its own rather than depending on wall clock. Beyond the self-tests it asserts the boot banner, that the blink thread and the 1 Hz application timer have both run (covering the LED path and the timer service), and that the mutex, queue, event-flag and semaphore counters are all non-zero. The suite was confirmed to exit 1 on a reintroduced bug and 0 on the fixed tree. The Robot Framework suite covers the same ground for renode-test, and the new test-nucleo-renode CI job mirrors test-polarfire-renode. main.c also drops a hardcoded 0x20018000 in favour of BSP_RAM_END now that board_config.h is in scope, with the 4 KB main-stack margin named.
…works (#52) templates/target/ documented a structure the repository does not have, and following it produced a build that could not configure. Its app/CMakeLists.txt compiled ../../../../apps/threadx_demo/main.c, but there is no apps/ directory and never has been, so the first thing a new contributor hit was a CMake error on a path that does not exist. Of the three shared root directories the template declared governed, only one was real: /bsp real - both framework targets implement board.h, led.h, console.h /cmake dead - cmake/utilities.cmake was referenced by nothing. All four targets carry their own copy, and the root file was byte-identical to the NUCLEO one apart from a license URL typo /apps absent - referenced by the template, docs/architecture.md, and the template's own CMake, but never created The template now says what the framework does: applications and toolchain files live with their target. The claim that applications have no compile-time dependency on vendor headers is retired rather than restated, because neither existing demo satisfies it - both include their board_config.h for memory sizing and vendor headers for board-specific startup self-tests. A portable shared application layer stays documented as a goal, labelled as one. templates/target/app/main.c is added because the template now points at it. It depends only on <tx_api.h> and the <bsp/...> contracts and uses static thread stacks, so it avoids needing the board's memory extents and will compile for any target implementing the interfaces. It is a starting point to grow in place, not a shared application. Also removed the template's dead SHARED_APP_DIR and its guarded include of ${SHARED_CMAKE_DIR}/gcc-arm-none-eabi.cmake, a file that was never added, so the include silently never fired. The template's BSP CMake now uses SHARED_BSP_DIR instead of a five-level relative path, matching what both real targets do, and CMAKE_C_STANDARD moves from 11 to 99 per AGENTS.md. The deleted cmake/utilities.cmake is recoverable from history if the intent was for it to become the shared location; nothing referenced it in this state, and leaving a duplicate that looks authoritative invites edits that have no effect. Verified the NUCLEO target still builds clean (22068 B ROM, 6000 B RAM) and its Renode suite still passes; neither target used the removed file. Assisted-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
… pattern (#53) The ARM job pinned 14.2.Rel1, chosen only because it was the newest release at the time. eclipse-threadx/threadx already pins 14.3.rel1 in ci_cortex_m.yml for the Cortex-M ports, so samplex was lagging the flagship repository rather than choosing between two versions. Both satisfy the AGENTS.md GCC 14 requirement; matching threadx means a toolchain bump is one reviewable line in each repository instead of a per-repository decision. The install steps now mirror ci_cortex_m.yml rather than paraphrasing it, which fixes three weaknesses in the version this replaces: - The archive was fetched with no integrity check at all. It is now verified with sha256sum against the published .sha256asc. - Roughly 150 MB was downloaded on every run. actions/cache, keyed on the pinned version, now avoids that. - wget -q hid transfer detail. curl -fsSL fails the step on an HTTP error, and a new step reports the resulting compiler version so the log records what actually built the ELF. Version and target move into job env vars (GCC_VERSION, GCC_TARGET) using the same names threadx uses, so the two files stay diffable and a future bump is a one-line change. Re-measured the NUCLEO validation record under the newly pinned compiler: 22064 B ROM, down 4 bytes from 14.2.1; RAM unchanged at 6000 B. The figures and the pin move together deliberately, since letting them drift is what left a stale 15.2.1 measurement in this file before. Verified under Arm GNU Toolchain 14.3.Rel1: clean build with -Wall -Wshadow -Wdouble-promotion -Werror, no new diagnostics from the point release, and the headless Renode suite still passes with all seven startup self-tests. Assisted-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
The PolarFire job pinned xPack riscv-none-elf-gcc 14.2.0-1 while the ARM job
now pins Arm GNU Toolchain 14.3.Rel1, so the two cross-compilers in this
pipeline were a minor release apart for no reason. xPack published v14.3.0-1
on 2025-10-23; moving to it puts both targets on GCC 14.3 and keeps the
AGENTS.md GCC 14 requirement satisfied.
The published SHA256 is updated alongside the version. The existing checksum
verification is kept as it was: this job already verified its download, which
is why it needed no other hardening.
Verified locally with xPack GNU RISC-V Embedded GCC 14.3.0:
- Clean build of polarfire_icicle_demo.elf.
- Headless Renode suite passes, exit 0, with all startup self-tests green:
_sbrk bounds, HWTimer catch-up clamp, PLIC Hart 1 configuration, the queue
round-trip, ThreadX ticks, the LM75 alarm, and the PLIC RX interrupt.
The linker warning about a LOAD segment with RWX permissions is unchanged by
this bump. It is emitted identically by 14.2.0 in the current pipeline, so it
predates this change and is left for separate treatment rather than folded in
here.
Assisted-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Two problems in the pipeline, one of them mine. The NUCLEO Renode job fetched renode-latest.linux-portable.tar.gz with no version pin and no checksum, while the PolarFire job three jobs above it already pinned Renode 1.16.1 and verified its SHA256. That pin landed in #49, so it was present in this file when #51 added the NUCLEO job; the new job was modelled on an older copy of the PolarFire step rather than the current one. The result was a suite whose emulator could change under it on any Renode release, with nothing verifying what was downloaded. The NUCLEO job now uses the same pinned, checksum-verified step as PolarFire. The checksum was recomputed from the published artefact rather than copied on trust. Separately, every run re-downloaded roughly a gigabyte: the xPack RISC-V toolchain at ~414 MB and Renode at ~52 MB in each of two jobs. All three are now restored by actions/cache, keyed on the pinned version so a future bump invalidates the cache instead of silently serving the old one. This completes what #53 started for the Arm toolchain. Caching only makes sense because these are now pinned. Caching an unpinned "latest" artefact would have frozen CI on whichever build happened to be fetched first, turning a reproducibility gap into an invisible one. All four jobs now follow the same shape: cache, install only on a cache miss, then put the tool on PATH as a separate step so it runs on hit and miss alike. The PolarFire job also gains a version-reporting step, matching the Arm job, so the log records which compiler produced the ELF. Verified both constructed download URLs resolve, and that the Renode 1.16.1 checksum matches the published artefact. Assisted-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
…#56) The framework's stated purpose is that application code can be built for any board implementing the `bsp/` contracts. Neither demo could be, because both `main.c` files reached past those contracts for two things no portable application can see: the board's memory extents, and the hardware specifics its startup self-tests assert on. Neither was ever application logic. The self-tests test the BSP - linker reservations, clock trees, interrupt controllers - so they belong in the BSP. Two new contracts move both behind the boundary: * `bsp/selftest.h` - `bsp_self_test()` runs the board's checks and reports each through an application-supplied callback, so message formatting (and therefore the choice between `printf()` and `bsp_console_write()`) stays with the application while the checks stay with the board. * `bsp/memory.h` - `bsp_ram_region()` reports what RAM the application may claim, clamped against whatever the board reserves. Both targets implement both, and both `main.c` files now include nothing but the C standard headers, `tx_api.h` and `<bsp/...>`. The NUCLEO byte pool comes out byte-identical at 88204 bytes. Prototyping `bsp_ram_region()` on the PolarFire first surfaced a latent bug there. Its `_sbrk()` bounded the heap at the end of DRAM, which is the same mistake the NUCLEO shipped with before #50: harmless only because nothing else claimed that memory. The moment `bsp_ram_region()` promises it to an application, an oversized `malloc()` could take memory holding thread stacks. The heap is now bounded against a documented 64 KB reservation that `bsp_ram_region()` skips, and a new self-test guards the bound the way the NUCLEO's test 4 does. Measured heap use is under 256 bytes, so the reservation has ample headroom. The PolarFire tick-rate compile-time check moved to `hwtimer.c`, next to the `TICK_CYCLES` constant it guards, since it needed ThreadX headers that a portable `main.c` should not have to pull in. Verified locally on both targets: clean builds plus `test_renode.py` green on Cortex-M4 and RV64. Both suites were also confirmed to still have teeth - weakening each target's `_sbrk()` bound back to the end of RAM makes them exit 1 (three failures on the NUCLEO, one on the PolarFire), so no assertion was lost in the move. Assisted-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
The framework documented a portable application layer it did not have: each
target owned its own demo under app/, so nothing checked that a demo could
actually move between boards. This adds apps/, moves the NUCLEO-F401RE demo
into apps/threadx_demo/main.c unchanged in behaviour, and has the PolarFire
SoC Icicle Kit build that same source as a second executable beside its LM75
monitor. CI runs it under Renode on 32-bit Cortex-M4 and 64-bit RISC-V and
asserts on the same console output from both, so the claim is now enforced
rather than stated.
apps/ holds portable demos; targets/<Vendor>/<BOARD>/app/ holds board-specific
ones, and a target's app/CMakeLists.txt picks either. The PolarFire LM75
monitor stays a target app because it genuinely models a sensor.
Linking a second executable first required removing a hard undefined reference:
polarfire_bsp's trap.c called console_rx_isr_callback(), a symbol only its own
demo defined, so any other application had to define a PolarFire-specific ISR
callback just to link. bsp/console.h gains a registration call in the shape
bsp_self_test() already established:
typedef void (*bsp_console_rx_fn)(char c, void *context);
void bsp_console_set_rx_handler(bsp_console_rx_fn handler, void *context);
The board stores a nullable pointer and checks it before dispatching, so bytes
arriving with no handler attached are dropped instead of faulting, and an
application that ignores console input defines nothing. The LM75 demo registers
its existing handler in main(); the NUCLEO-F401RE polls USART2 and so stores a
handler it never invokes, which keeps the contract uniform enough to register
against unconditionally. A weak symbol was rejected: it keeps the up-call and
is a GCC extension in a C99 codebase.
Building the demo for a second architecture found two real defects:
- Every %lu in the demo was wrong on one target. ThreadX defines ULONG as
unsigned long on the Cortex-M4 port and unsigned int on the RISC-V 64 one,
so each value now casts to unsigned long, matching the existing idiom in
the LM75 demo.
- Both boards' _sbrk() underflow self-test asked for a fixed -128, which is
an underflow only when nothing has allocated yet. The NUCLEO's passed by
accident of a printf buffer malloc that failed against a small reservation;
the PolarFire's failed outright once a demo reached printf first. Both now
hand back one byte more than has ever been taken, which underflows whatever
ran before them.
Thread stacks are sized in machine words rather than bytes, since every saved
register and the newlib printf() call chain double in width on a 64-bit hart:
1024 bytes on Cortex-M4 as before, 2048 on RISC-V, measured peak 1048.
Measured PolarFire heap use under printf, the first stdio on that board, is
2944 bytes; the run also completes with BSP_HEAP_RESERVE_BYTES cut to 4 KB, so
the 64 KB reservation holds unchanged.
Verified locally on both toolchains: three Renode suites green, and with the
_sbrk() bound deliberately widened the self-tests still fail - two checks on
the NUCLEO-F401RE, one on each PolarFire executable.
Assisted-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
The per-edit disclosure named the product and model, so every tool and every
model version appended another line rather than recognising the one already
there. Deduplication was by exact string, which a version bump defeats.
Every file now carries exactly one line, fixed text naming no product:
Portions of this file were generated with AI assistance.
written with the comment character that file already uses. Precise attribution
stays on the commit, where the Assisted-by trailer is dated and attached to the
diff it describes. A header line cannot keep that record honest, because the
code it names gets rewritten and the line stays.
Comment-only, 32 files: every removed line was a disclosure line, every added
line is the fixed text, and no file is left with zero or more than one. Nested
repositories were excluded, so no submodule content or gitlink is touched.
Assisted-by: Claude Code (Opus 5) <noreply@anthropic.com>
samplex demonstrates Eclipse ThreadX and NetX Duo on Cortex-M4 and RISC-V, but had no reference enablement for NXP's Cortex-M7 crossover parts, and no way to exercise the network stack in CI without hardware. This adds `targets/NXP/MIMXRT1064-EVK/`, built from `templates/target/` and implementing the `bsp/include/bsp/` contract, with three demos: `threadx_basic` (scheduling, timers, LED), `netx_echo` (ICMP, UDP and TCP echo on port 7) and `netx_trng_console` (on-chip TRNG behind a single-session TCP shell on port 23, serving one connection at a time). The ENET and KSZ8081 PHY drivers are vendored rather than tracked from `getting-started`, which is on the same archive track as `iot-devkit`. Every SDK and CMSIS download is pinned to a tag or commit and SHA256-verified. A Renode platform model and a headless Python runner join the existing CI, reusing the pinned toolchain and Renode steps from #53 and #55. Renode 1.16.1, all three demos green: `threadx_basic` asserts the worker thread runs at tick 100; `netx_echo` asserts link up, ARP, ICMP reply and 23-byte UDP and TCP echoes across two emulated nodes; `netx_trng_console` asserts four distinct non-zero entropy words, remote LED toggle, uptime telemetry, and that an over-long command line is refused without dropping the session. Not run on hardware. The README records what the emulator stubs: CCM and ANALOG are tag stubs whose registers read back fixed values, the 600 MHz banner is a compile-time constant, and Renode's TRNG model implements neither the programming sequence nor the ENT15 block-consume semantics, so the driver's bring-up is unverified on silicon. Signed-off-by: Ali Eissa <ali.eissa.dev@gmail.com> Assisted-by: Google DeepMind Antigravity (Gemini 3.8 Flash) <noreply@antigravity.google>
The NXP target and #69 were in flight at the same time, so the target landed carrying the older per-edit disclosure that #69 replaced everywhere else. Eleven files named the product and model inside the header's Contributors block, and nine carried no disclosure at all. All twenty now carry the same fixed line every other file in the repository uses, written with the comment character already in the file. The Contributors blocks are untouched: only the AI disclosure moves, and precise attribution stays on the Assisted-by trailer where it is dated and attached to its diff. Six vendored files are deliberately excluded. startup_mimxrt1064.S, the two KSZ8081 PHY sources and the three NetX driver sources carry only their upstream NXP or Microsoft copyright, with no Eclipse ThreadX line added, so they hold no AI-generated work to disclose. tx_initialize_low_level.S and tx_user.h do carry that line and are included. Comment-only, 20 files: every removed line was a disclosure line and every added line is the fixed text, with no file left holding zero or more than one. The target builds clean with Arm GCC 14.3.Rel1. Assisted-by: Claude Code (Opus 5) <noreply@anthropic.com> Signed-off-by: Frédéric Desbiens <frederic.desbiens@eclipse-foundation.org>
Clarified the boundary between Newlib system calls, the BSP, ThreadX, and the ThreadX POSIX compatibility layer. Assisted-by: Codex (GPT-5) <noreply@openai.com>
The generic contributor guide omitted SampleX build, test, and submission practices. The guide now covers C99, board-specific toolchains and tests, the six Linux CI jobs, Renode verification, attribution, and release practices. Local Markdown links resolve and git diff --check passed. Build tests were not run for this documentation change. Assisted-by: Codex (GPT-6-Sol) <noreply@openai.com>
Added an STM32 NUCLEO-F429ZI sample SampleX had no NUCLEO-F429ZI target. The NUCLEO-F767ZI one was the closest thing, and a board this common being absent meant starting from a target for a different family. The new target is derived from the F767ZI one and keeps its shape: the same tasks and the same IO, moved onto STM32F4 peripherals. It brings its own startup, linker script and HAL configuration, a threadx_basic demo, the CMake toolchain files, and build and SDK fetch scripts for Linux and Windows. The F767ZI target picks up the small corrections that fell out of the comparison. The STM32F429 SVD is fetched rather than carried. It is ST's file under Apache-2.0 while this repository is MIT, and at 62106 lines it was most of the change. fetch_sdk.sh now takes it from the CMSIS device family pack with the pack version pinned and its digest checked, the way the toolchains are pinned, and NOTICE.md declares it alongside the HAL, CMSIS Device and CMSIS Core that were already fetched. Nothing is lost: the SVD is read only by the optional Segger Ozone configuration and no build consumes it. CI green. The fetch was run from a clean tree: the pack downloads, the digest matches and tools/STM32F429.svd arrives at 2118587 bytes. Assisted-by: Claude Code (Opus 5) <noreply@anthropic.com> Co-authored-by: Jacob Rosén <accounts.eclipse.org.script835@passmail.net> Co-authored-by: Frédéric Desbiens <frederic.desbiens@eclipse-foundation.org>
* Fix CORE-V CLI host test mocks * Added the licence header to the four new mock files The mocks arrived without one. Every other file in this directory carries the MIT header, and a source file entering an Eclipse project without a copyright line is the kind of omission that is cheap now and awkward later. The header is the plain MIT one rather than the AI disclosure variant the neighbouring mocks carry, because nothing here establishes how these were written and the disclosure is a statement about that. Build clean and the CLI host tests pass. Assisted-by: Claude Code (Opus 5) <noreply@anthropic.com> --------- Co-authored-by: divyanshisingh987456321 <sdivyanshi576@gmail.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Brings
mainup to the 6.5.2.202603 release content: twenty-one commits adding the STM32 NUCLEO-F429ZI sample, the NXP i.MX RT1064-EVK target with three demos and Renode CI, the PolarFire SoC Icicle Kit target, and the generic BSP framework the targets were moved onto, together with pinned Arm and RISC-V toolchains, cached toolchain fetches, and the contribution guide rewrite.maincarries one commitdevdoes not, the earlier fix for the CORE-V CLI host tests.devhas the same fix, so the merge is clean.Two follow-ups this deliberately leaves out. The library submodules under
libs/are still pinned at 6.5.0.202601 series commits and will be repointed at the releasedmasterof each product, with.gitmodulesswitched tobranch = master, in a separate change on top of this one. Thedevpins move back to trackingdevafter the release is published.