Skip to content

Added an Erbium example to the RISC-V64 GNU port - #787

Merged
fdesbiens merged 3 commits into
eclipse-threadx:devfrom
AFOliveira:erbium-port
Sep 30, 2026
Merged

fdesbiens merged 3 commits into
eclipse-threadx:devfrom
AFOliveira:erbium-port

Conversation

@AFOliveira

@AFOliveira AFOliveira commented Sep 30, 2026 •

Copy link
Copy Markdown

ThreadX had no Erbium board example. The platform needs board-specific startup for its partial F extension, 4 KiB trap-vector alignment, Shakti UART, machine timer and PLIC behavior.

Added a machine-mode example that runs the standard eight-thread demo from MRAM with the soft-float lp64 ABI and no C library. It configures the timer, polling UART and PLIC without changing shared port files. UART output now waits with interrupts enabled and protects only the final FIFO check and byte write; PLIC enable-word updates are protected against interruption. Two simulator regression tests cover both races.

GCC 15.2.0 and Ninja built the images without warnings. On erbium_emu at the revision in the README, the 100-million-cycle demo run reported all eight threads, five thread 0 wakeups and 26 cycles of each semaphore and mutex pair. Both regression tests failed on the original code and pass with the fixes. AI disclosure and port consistency checks passed. The contributor also reported five UART interrupts and an illegal-instruction trap in separate test images. The simulator does not validate physical baud timing or the silicon timer rate; this was not run on silicon.

ThreadX had no board support for Erbium, the OpenHW Foundation CORE-ET RISC-V platform
that Zephyr and NuttX support. Its hart implements only part of the F extension, needs a
4 KiB aligned mtvec and uses the original Shakti UART.

The example runs the standard demo on hart 0 in machine mode. It builds the library and
the demo for rv64imc_zicsr_zifencei with the soft-float lp64 ABI and links without libc
or libgcc, so the pinned riscv64-unknown-elf toolchain can build it. It programs the
machine timer, a polling UART console and the PLIC, writing the source priorities and
threshold that silicon hardwires because the simulator resets them to 0. No shared file
changes.

The demo built without warnings and ran on erbium_emu from et-platform 836a4ab, with all
eight threads reporting and five thread 0 wakeups in 100M cycles, which matches the 2
MHz tick. Separate test images took five PLIC UART interrupts through the ThreadX ISR
path and halted with mcause 2 on an illegal instruction. check_ai_disclosure.sh and
check_ports.sh passed.

Assisted-by: Claude Code (Opus 5.5) <noreply@anthropic.com>
@fdesbiens

Copy link
Copy Markdown
Contributor

Hi @AFOliveira!

Thank you very much for this contribution. I just authorised the CI workflow. I'll check back in a while to see if there are any complaints from it.

Long polling UART writes can mask timer interrupts across several tick periods.
PLIC enable-word updates can overwrite a change made by an interrupt handler.
The board example had no simulator tests for either case.

Added two simulator images and a runner. One compares hardware timer progress with
ThreadX ticks after a long print. The other toggles one PLIC source in timer
context while a thread changes another. Both tests fail on the PR code and pass
with the corresponding local fixes.

GCC 15.2.0 and Ninja built both images. erbium_emu reproduced both failures;
control runs passed both tests. Port consistency checks passed. No silicon run.

Assisted-by: Codex (GPT-6-Sol) <noreply@openai.com>
Polling UART output held machine interrupts off for an entire string, which
could lose ThreadX ticks. PLIC enable-word changes could overwrite an update
made by an interrupt handler.

The UART now polls with interrupts enabled and protects only the final status
check and byte write. PLIC enable and disable changes are protected across
their read-modify-write. The README explains the new simulator tests.

Both simulator tests failed on the original code and passed with these fixes.
The 100-million-cycle demo run reported all eight threads and five thread 0
wakeups. AI disclosure and port consistency checks passed. No silicon run.

Assisted-by: Codex (GPT-6-Sol) <noreply@openai.com>
@fdesbiens

Copy link
Copy Markdown
Contributor

Hi again @AFOliveira.

I pushed two fixes to the PR: the polling UART now allows timer interrupts while waiting, and PLIC enable changes are protected from interrupt races. I also added simulator tests that fail on the original code and pass with the fixes. The standard demo still runs in erbium_emu; I cannot test on silicon (unless you guys eventually send me something, wink, wink). Could you review the changes and share any concerns, especially about hardware behaviour?

@fdesbiens

Copy link
Copy Markdown
Contributor

CI is happy with my changes applied. So, if my proposed fixes don't set your board on fire, I will merge this today @AFOliveira. Just let me know.

@AFOliveira

Copy link
Copy Markdown
Author

@fdesbiens LGTM!

Emulator is the best we can get for the next two months ;)

@fdesbiens
fdesbiens merged commit fb4a876 into eclipse-threadx:dev Sep 30, 2026
15 checks passed
@fdesbiens

Copy link
Copy Markdown
Contributor

Merged! This will be one of the hilights of the Q3 2026 release.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants