Commit graph zephyr/scripts
Author SHA1 Message Date
Anas Nashif
6780956c7c manifest: move chre to be an external module
Remove chre from the manifest and all the integration of chre in zephyr
and move it to an external module.

Nothing in zephyr depends on chre.

Signed-off-by: Anas Nashif <anas.nashif@intel.com>
2026-09-12 07:53:26 -04:00
Brian Cain
5ad3094a54 boards: add QEMU hexagon board
Add the qemu_hexagon board definition targeting the H2 hypervisor
guest on QEMU's hexagon virt machine.

Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
2026-09-12 07:52:39 -04:00
Brian Cain
5761d7d707 hexagon: add architecture port
Add Hexagon DSP architecture support to Zephyr RTOS, targeting the
Qualcomm Hexagon V67+ ISA running as a guest under the H2 hypervisor.

This includes:
- Architecture scaffolding (Kconfig, CMakeLists, arch selection)
- Public headers (arch.h, thread.h, exception.h, error.h)
- Core runtime: context switch, interrupt/exception handling, idle, TLS
- Memory management stubs for flat-memory H2 guest model
- SoC support for QEMU hexagon virt machine
- CMake/LLVM toolchain integration for hexagon cross-compilation

Hexagon uses H2's GEVB (Guest Event Vector Base) for interrupt dispatch
rather than a traditional function-pointer vector table, so
GEN_IRQ_VECTOR_TABLE is disabled by default.

Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
2026-09-12 07:52:39 -04:00
Jordan Yates
e293e1dd47 scripts: twisterlib: fix snippet filtering
The generated cmake snippet logic in `snippets_generated.cmake` requires
a full board name match, enforced by the anchoring characters `^...$`,
to apply the relevent overlays.

The python `testplan.py` `required_snippets` filtering currently
enforces a looser filtering of `re.search`. This allows boards to pass
the twister filtering that don't actually support the required snippet.

For example a snippet with board regex of `/nrf54l15dk/nrf54l15/cpuapp/`
when compiled for `nrf54l15dk/nrf54l15/cpuapp/ns` would pass the
twister filtering step, but not apply any snippet in cmake.

Switch `re.search` to `re.fullmatch` to duplicate the CMake logic.

Signed-off-by: Jordan Yates <jordan@embeint.com>
2026-09-11 17:32:25 +02:00
Benjamin Cabé
81e94114a0 scripts: zspdx: don't rename SPDX 2.x packages after their CPE product
A component carrying a CPE was written out under the CPE product name
while its SPDXID and relationships kept using the component name, and the
SPDX 3.0 serializer never did this. Keep the component name and let the
CPE fill in only the supplier and version.

Assisted-by: Claude:opus-5
Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
2026-09-11 17:26:46 +02:00
Benjamin Cabé
244e526b20 twister: coverage: ignore unreadable objects in the ztest stage
commit d2b568433a ("twister: coverage: keep the report when one object
is unreadable") added the flag to the first gcovr call only, so the
ztest filter stage still exits 64 and drops both reports.

Assisted-by: Claude:opus-5
Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
2026-09-11 17:18:40 +02:00
Benjamin Cabé
02e9787013 ci: coverage: drop function positions before merging tracefiles
gcovr records a function's source position only when gcov reports "JSON
format version: 2", which gcc grew in 14. The SDK gcov is 14.3 and the
container's host gcov is 13.3, so the mps2 and qemu legs carry positions
and the native_sim and unit_testing legs do not. Merging both aborts
with a KeyError as soon as a function sits on different lines, leaving
no merged.xml and publishing the Doxygen coverage as the project number.

Aligning the two gcov versions would avoid it as well, but dropping the
positions keeps the merge working whenever they diverge again. Nothing
downstream reads them.

Verified on the four tracefiles of run 34316113625: both merge commands
exit 0 and the report covers 2008 files at 50.59%.

Assisted-by: Claude:opus-5
Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
2026-09-11 17:18:40 +02:00
Zhaoqi Xu
8db8e202a0 scripts: kconfig: strip whitespace in shields_list_contains
$(shields_list_contains, foo) looks for " foo" and silently returns n
even when "foo" is in SHIELD_AS_LIST. Shield names cannot contain
spaces, so strip leading and trailing whitespace, warn, and look up
the trimmed name.

Fixes #99457

Signed-off-by: Zhaoqi Xu <lzy00419@outlook.com>
2026-09-11 05:24:32 -04:00
Benjamin Cabé
56f08dce75 scripts: zspdx: drop the dead scan_document() shim
It was left behind by the Document to SBOMGraph migration and only ever
raises NotImplementedError, so it cannot provide the compatibility it
claims. Nothing calls it.

Assisted-by: Claude:opus-5
Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
2026-09-11 05:24:10 -04:00
Benjamin Cabé
dd1a5f21fc scripts: zspdx: take the SPDX license list from license-expression
The vendored list was a copy of SPDX license list 3.12 from 2021, so the
288 identifiers added since were demoted to custom LicenseRef- entries.
Read the list from license-expression, already pulled in by reuse, which
tracks the published one.

Assisted-by: Claude:opus-5
Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
2026-09-11 05:24:10 -04:00
Henrik Brix Andersen
3636778087 scripts: requirements: actions: refresh pinned versions
Run the uv command to update the pinned versions in
requirements-actions.txt.

Signed-off-by: Henrik Brix Andersen <hebad@vestas.com>
2026-09-10 10:17:43 +02:00
Henrik Brix Andersen
ff5a236b4c scripts: requirements: actions: basic: refresh pinned versions
Run the uv command to update the pinned versions in
requirements-actions-basic.txt.

Signed-off-by: Henrik Brix Andersen <hebad@vestas.com>
2026-09-10 10:17:43 +02:00
Bill Waters
c4224431c2 twister: skip token-pasted ZTEST names in the static scan
The twister source scanner extracts ZTEST() testcase names with the
regex [a-zA-Z0-9_]+. For cases whose name is built with the ##
token-paste operator, e.g.

    ZTEST(dma_m2m_loop, test_dma##idx##_m2m_loop)

the regex stops at the first # and captures "test_dma", which after the
"test_" prefix is stripped registers a phantom subcase "<suite>.dma".
That case never runs (the real, fully expanded cases such as
test_dma0_m2m_loop are only produced at build time), so every run of
tests/drivers/dma/loop_transfer and other macro-generated ztest suites
reports it as "None status".

Add a negative lookahead so a testcase name immediately followed by a
word character or # is not matched. Token-pasted names are therefore
ignored by the static scan and no longer create phantom subcases; the
real cases continue to be discovered from the harness output at runtime.

Add a scan_file unit test covering a suite that mixes a literal ZTEST
case with token-pasted, macro-generated cases, and extend the
get_all_testsuites expectation with the new fixture's literal case.

Assisted-by: AI (GitHub Copilot)
Signed-off-by: Bill Waters <bill.waters@infineon.com>
2026-09-09 18:14:13 -04:00
Jeremy Bettis
d31fa61e7c twister: coverage: ignore gcov and child errors in lcov v2
When using LCOV v2 with --coverage, geninfo can encounter empty or
invalid .gcda files (such as 0-byte nsi_tasks.gcda generated under the
native simulator). In LCOV v2, gcov errors and parallel child worker
failures are treated as fatal unless explicitly ignored.

Add "gcov,gcov" and "child,child" to the --ignore-errors list in
twister's Lcov tool when LCOV v2 is detected so that coverage capture
does not fail on non-fatal gcov and child errors.

Assisted-by: Antigravity:gemini-1.5-pro
Signed-off-by: Jeremy Bettis <jbettis@google.com>
2026-09-09 18:14:09 -04:00
Ugo Marchand
0097eb81a0 scripts: tracing: test the CTF to Perfetto exporter
Add unit tests that build a CTF trace from the tracing subsystem's own
TSDL metadata, so the event ids and field layouts they exercise are the
ones a build emits rather than a copy of them that can drift. They cover
the lane routing, that records keep the time they happened, that a trace
ending mid-run keeps its running thread, that payload strings such as a
syscall name reach the output, and that a metadata mismatch is an error
while a half-written trailing record is not.

Run them in the misc. pylib workflow, beside the build_helpers tests it
already runs out of scripts/tests. Its path filter gains subsys/tracing
so that a change to the TSDL metadata, which is the input these tests are
built from, reruns them; it was listed for push only. MAINTAINERS.yml
gains the new directory so it lands in the tracing area, as the script it
tests already does.

Signed-off-by: Ugo Marchand <marchand.ugo@orange.fr>
Assisted-by: Claude:claude-opus-5
2026-09-09 07:43:05 +02:00
Ugo Marchand
eb1b9a0852 scripts: tracing: add a CTF to Perfetto trace exporter
Zephyr's CTF traces can be read as text with parse_ctf.py or on the
console with trace_viewer.py, but there is no way to open one in a hosted
timeline UI without installing babeltrace2 and writing a converter.

Add ctf2perfetto.py, which converts a CTF trace to the Chrome/Perfetto
Trace Event Format. It reuses the dependency-free CTF decoder of
trace_viewer.py, so it needs nothing but Python 3, and it derives the
running-thread and ISR timelines from the same segmentation that drives
the viewer, so both tools show the same schedule. A trace normally stops
mid-run, so the thread and the ISR it ends inside are closed at the last
recorded timestamp rather than left out of the timeline.

Threads get one lane each and kernel objects are routed to fixed lanes
(ISR, mutex, semaphore, timer, net, socket, GPIO) so a lane keeps its
meaning across traces; an event naming no thread, such as k_sleep_enter,
lands on the lane of the thread that was running when it was recorded.
Only the lanes a trace reaches are named, so a trace that does no
networking opens no empty Socket track.

The TSDL metadata is read from next to the trace, which is where the
build wrote it and where babeltrace2 reads it from, or from --metadata.
Only that file describes the trace: a CTF record carries no length, so
metadata that disagrees about an event's payload does not merely mislabel
that record, the decode desyncs and everything after it is lost. Missing
metadata, and a record whose event id the metadata does not describe, are
therefore errors naming what is wrong rather than a partial export.

Zephyr already writes this format once, in
scripts/instrumentation/zaru.py, which renders context switches as
ftrace sched_switch lines so that Perfetto draws a CPU scheduling
track. That form needs a CPU id per switch and the CTF metadata
carries none: thread_switched_in and thread_switched_out hold a thread
id and a name. Filling the column with a constant would draw an SMP
trace as if it had run on one core, so the schedule is drawn as
per-thread slices instead, which claim no more than the trace records.
A sched_switch track can be added later without changing what is
written here, and would carry a real prev_state, which zaru.py has no
source for and leaves constant.

Signed-off-by: Ugo Marchand <marchand.ugo@orange.fr>
Assisted-by: Claude:claude-opus-5
2026-09-09 07:43:05 +02:00
Benjamin Cabé
fb0d476b04 ci: coverage: skip files with no instrumented lines
gcovr 8 reports files that have no instrumented lines at all, which
gcovr 6 left out of the tracefile. The report generator divides by the
line count and so dies with ZeroDivisionError on them. Leave them out,
as the older tracefiles did.

Assisted-by: Claude:opus-5
Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
2026-09-09 07:42:45 +02:00
Benjamin Cabé
d2b568433a twister: coverage: keep the report when one object is unreadable
A run picks a single gcov, but a suite may ask to be built with another
toolchain through integration_toolchains, and a target that faults
mid-dump leaves a truncated .gcda behind. Either one makes gcovr exit
without writing coverage.json, so a whole platform contributes nothing
even though every other object was fine.

Ask gcovr to report what the rest of the run covered instead. Objects
it cannot read are dropped without a message, which is the price of not
losing every other object with them.

Assisted-by: Claude:opus-5
Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
2026-09-09 07:42:45 +02:00
Benjamin Cabé
7b73301772 scripts: requirements: bump gcovr to 8.6
gcovr 6.0 aborts the whole run when it meets an object it cannot read,
and its --gcov-ignore-errors only knows "no_working_dir_found", so
there is no way to ask it to carry on. 8.x adds source_not_found and
output_error, which is what a coverage run needs to survive a single
bad object.

Assisted-by: Claude:opus-5
Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
2026-09-09 07:42:45 +02:00
Benjamin Cabé
b21cce773c twister: coverage: compare the gcovr version numerically
get_version() returns a string, so "10.0" >= "7.0" is false and a gcovr
10 release would silently lose --gcov-object-directory and the
suspicious_hits tolerance. Parse it instead.

Assisted-by: Claude:opus-5
Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
2026-09-09 07:42:45 +02:00
Emil Gydesen
ac94a7decc scripts: ci: request reviewers in batches of 15
A single GitHub review request accepts at most 15 users, but
_request_reviews() sent the whole candidate list in one call and, when
GitHub rejected it, retried with only the first 15 and gave up on the
rest. Those left over were merely mentioned in a comment, and only a
later run of the script - where the first 15 are filtered out as
existing reviewers - added them. That is why a PR received a subset of
its reviewers on the first run and more on the second.

Split the candidates into batches of REVIEWER_REQUEST_BATCH (15) and
issue one request per batch, so every eligible reviewer is added on the
first run. A rejected batch is now retried one user at a time, so a
single bad candidate (deleted account, lost collaborator status) no
longer costs the rest of its batch their review request; only the users
that still fail are mentioned instead.

Also delete the reviewer-mention comment once a run has nobody left to
mention, so the PR stops claiming that people could not be requested
after they have been.

Verified with scripts/tests/ci/test_set_assignees.py, extended with
tests for the batching, the per-user fallback and the comment cleanup.

Signed-off-by: Emil Gydesen <emil.gydesen@nordicsemi.no>
2026-09-08 19:18:19 -04:00
Anas Nashif
90d415ddc5 twister: harness: catch unexpected faults in ignore_faults tests
Tests that trigger faults on purpose set ignore_faults, which disables
the generic ">>> ZEPHYR FATAL ERROR" crash detection entirely. When
such a test then crashes for real (e.g. testing.ztest.error_hook), the
crash went unrecognized and the run was reported with a twister-side
artifact such as "unexpected eof" or a timeout.

Ztest's fatal-error and assert hooks already make the distinction the
harness needs: they print "Fatal error was unexpected, aborting..." or
"Assert failed was unexpected, aborting..." right before halting when
the fault was not declared as expected by the test. Several tests with
custom hooks print the same message, some in lower case.

Match these markers case-insensitively in Harness.process_test() and
set harness.fault even when fail_on_fault is off, so the handlers
report such runs as "Fault detected while running test" like any
other crash. The hooks' expected-fault messages ("Fatal error
expected as part of test case.") do not contain the markers and are
unaffected.

Assisted-by: Claude:claude-fable-5
Signed-off-by: Anas Nashif <anas.nashif@intel.com>
2026-09-08 16:06:05 +02:00
Anas Nashif
36f7f1f176 twister: report unexpected faults as crashes, not timeouts
When a test crashes with an unexpected fatal error the target halts
and never prints a verdict, so the QEMU monitor kept reading until
the full per-test timeout expired and the run was reported as
"Timeout". The timeout was a twister artifact, not the failure: the
console already contained the ">>> ZEPHYR FATAL ERROR" banner. Other
simulators exit on such a crash and got reported differently again
(e.g. "failed (rc=2)" on mps4 FVP), so the same crash produced
inconsistent results across platforms.

The harness already tracks unexpected fatal errors in harness.fault
(tests that fault on purpose opt out with ignore_faults), and any run
with a recorded fault is already doomed to fail once a verdict
arrives. Use that flag in the handlers:

- The QEMU monitor loops (POSIX and Windows) record the failure as
  "Fault detected while running test" as soon as the fault banner is
  seen and switch to the short post-status grace period, capturing
  the rest of the crash dump instead of waiting out the timeout. A
  subsequent EOF no longer overwrites the recorded fault reason with
  "unexpected eof".
- BinaryHandler's output loop stops after the same grace period once
  a fault is seen, covering simulators such as Arm FVP.
- Handler._update_instance_info() prefers the fault over the derived
  "Timeout" or "Exited with <rc>" reasons, so every handler
  (including device testing) reports such a crash the same way.

The reason string is shared as FAULT_REASON in constants.py so the
harness and the handlers cannot drift apart.

Assisted-by: Claude:claude-fable-5
Signed-off-by: Anas Nashif <anas.nashif@intel.com>
2026-09-08 16:06:05 +02:00
Egemen Tuncarslan
6a282a0a8b tests: twister: cover the build.log side of size_calc
SizeCalculator takes the footprint numbers twister reports from the last
"Memory region" table in build.log. Everything between finding that table
and the four numbers it ends up with is string handling, and none of it
was covered: the module sat at 16% under the twister suite, with no test
file of its own.

These drive that path with build logs written by the test: finding the
table (and the last one when there are two, and not a line that merely
mentions it), taking its lines, splitting the columns, converting the
units, and the four numbers that come out. The ELF analysis is stood in
for, since none of this is about the ELF.

Coverage of the module goes from 16% to 67%.

Signed-off-by: Egemen Tuncarslan <egementuncarslan@hotmail.com>
Assisted-by: Claude:claude-opus-5
2026-09-07 10:31:39 +02:00
Josh DeWitt
7b4dab34ff runners: jlink: Respect --reset option for attach command
The --reset option was ignored for the 'attach' command. Issue a monitor
reset on attach if --reset is passed to match the 'debug' command.

Signed-off-by: Josh DeWitt <josh.dewitt@garmin.com>
2026-09-04 21:45:45 -04:00
Egemen Tuncarslan
30beaec88f twister: reports: don't look past the start of the build log
_parse_build_failure decides why a link failed from the line before the
one carrying "error: ld returned":

    elif "error: ld returned" in line:
        if last_warning:
            return last_warning
        elif "overflowed by" in lines[i - 1]:
            return "ld.bfd: region overflowed"
        elif "ld.bfd: warning: " in lines[i - 1]:
            return "ld.bfd:" + lines[i - 1].split("ld.bfd:", 1)[-1]

At i == 0 that is lines[-1], the last line of the log. So a log whose
first line is the linker error is described by its last line -- and that
line need not even come from the same file, since JsonReport.create()
appends the handler's stderr to the build log before parsing it.

The same failure then gets reported two ways, depending only on whether
anything was printed before the linker error:

  [ld error, "ninja: build stopped.", "...overflowed by 4096 bytes"]
      -> "ld.bfd: region overflowed"

  ["[1/2] Building ...", ld error, "ninja: build stopped.",
   "...overflowed by 4096 bytes"]
      -> "/usr/bin/ld.bfd: error: ld returned 1 exit status"

Nothing precedes the first line, so the answer is the line itself, which
is already what the function returns when the previous line says nothing
in particular.

scripts/ci/twister_report_analyzer.py reads lines[i - 1] the same way,
parsing the same linker output for the CI job summary. It is a separate
tool with no tests of its own, in a directory this change does not
otherwise touch, so it is left for a change of its own.

Signed-off-by: Egemen Tuncarslan <egementuncarslan@hotmail.com>
Assisted-by: Claude:claude-opus-5
2026-09-04 21:45:34 -04:00
Egemen Tuncarslan
7fce8746d9 tests: twister: add tests for reports.py
reports.py had no test file. It is 528 statements -- the JSON and XUnit
report writers, and the parsers that turn a build log into the short
reason twister puts in its reports -- and the twister suite covered 10%
of it, all of that incidental to other tests.

This covers the parts that need no fixtures: ReportStatus, the JSON
encoder, process_log, get_detailed_reason, and the two build-failure
parsers against the shapes of log they are written for. Coverage of the
module goes from 10% to 21%.

Signed-off-by: Egemen Tuncarslan <egementuncarslan@hotmail.com>
Assisted-by: Claude:claude-opus-5
2026-09-04 21:45:34 -04:00
Daniel Leung
7e4bcddd57 twister: try harder to terminate processes
For some reasons, there are always lingering QEMU processes
after twister has finished on my computer. So need to try
harder to make sure the QEMU process tree is terminated.

Signed-off-by: Daniel Leung <daniel.leung@intel.com>
2026-09-04 21:45:30 -04:00
Appana Durga Kedareswara rao
b3d5c4baec scripts: coredump: use live per-CPU snapshots and reorder panicking thread
With the target now exporting (on arm64) per-CPU live register snapshots
and the host qfThreadInfo walk already enumerating one current thread per
CPU, teach the host coredump scripts to consume those snapshots and to
present the panicking thread as GDB's "Thread 1".

gdbstub.py reorders the panicking CPU's current thread to the front of
the per-CPU thread list so GDB's "Thread 1" carries the real ESF
registers. The panicking thread is identified via the zero-payload
snapshot marker, which is unambiguous; the fallback heuristic
("whichever CPU has no live snapshot") is used only when no marker is
present and can mislabel threads when some other CPU's freeze also timed
out.

arm64.py prefers a thread's live snapshot over its callee_saved
approximation when one exists, skipping the zero-payload marker entries
(which carry no register data by design), so a thread that was actually
running on another CPU at panic time shows a correct backtrace from its
real live registers.

Signed-off-by: Appana Durga Kedareswara rao <appana.durga.kedareswara.rao@amd.com>
2026-09-04 21:45:11 -04:00
Appana Durga Kedareswara rao
3b3bd23a9d debug: coredump: arm64: freeze other CPUs and capture live registers
A thread actively running on another CPU at panic time was previously
invisible to real debugging: coredump only captured the panicking CPU's
exception frame, so every other thread's registers came from its
k_thread.callee_saved struct -- correct for genuinely sleeping threads,
but stale (reflecting whenever it last voluntarily context switched) for
one that's actually running elsewhere right now.

Add CONFIG_DEBUG_COREDUMP_SMP_FREEZE_CPUS (default y where the arch sets
ARCH_SUPPORTS_COREDUMP_SMP_FREEZE, i.e. arm64 Cortex-A SMP). On panic,
coredump() freezes every other online CPU before dumping and thaws them
after the memory-region walk, and emits each frozen CPU's live registers
as a new coredump section (COREDUMP_CPU_SNAPSHOT_HDR_ID, tagged with CPU
index and thread pointer, reusing the arch-info block register layout).
The panicking CPU (never frozen, since freeze only targets other CPUs)
emits a zero-payload marker recording only which thread was panicking
there, which the host side uses to identify it unambiguously.

arm64 implementation (arch/arm64/core/smp.c, coredump.c): send a new SGI
to every other online CPU. Each handler captures its exact live state --
x0-x18/lr/spsr/elr via the arch_esf that _isr_wrapper() stashes at a
fixed, nesting-independent slot on its IRQ stack, plus x19-x29 via inline
asm (valid per AAPCS64) -- then spins holding whatever it held before
being frozen, untouched, until the dump finishes, and resumes via the
standard exception-return path exactly where it was interrupted. This
matters because a panic here can be recoverable (this tree's own
coredump_threads test doesn't halt/reboot after dumping).

The SGI uses a deliberately low priority (SGI_COREDUMP_FREEZE_PRIO), not
IRQ_DEFAULT_PRIORITY: a frozen CPU never returns from its handler so
_isr_wrapper() never EOIs, and per GIC priority rules only a strictly
higher-priority interrupt can preempt a still-active one. At the default
priority a frozen CPU could not service same-priority peripheral
interrupts (confirmed on hardware as Ethernet TX-done starvation during
the UDP backend); the lowest usable priority lets everything else keep
making progress while a CPU waits.

The freeze/thaw handshake uses two separate per-CPU signals: freeze_state
(IDLE/REQUESTED/CAPTURED) and a dedicated release_requested flag that
only thaw writes. Kept separate so a late-arriving CPU (whose SGI was
delayed past the freeze-side timeout) still sees a release signal instead
of stomping it with its own CAPTURED update and spinning forever; thaw
sets release_requested unconditionally for every other CPU. The handler
wait is also bounded by a 60-second wall-clock backstop (k_cycle_get_32(),
safe from any context) so no CPU is ever stuck indefinitely. A CPU that
never responds within the freeze-side timeout (never booted, or stuck
with IRQs masked) is skipped and never blocks the dump.

The host coredump log parser learns to parse the new snapshot section.

Signed-off-by: Appana Durga Kedareswara rao <appana.durga.kedareswara.rao@amd.com>
2026-09-04 21:45:11 -04:00
Christoph Busold
158ebbd44c kernel: userspace: Support arbitrary futex addresses
This removes k_futex from the kobject table and allows any address
accessible to userspace to be used as futex and fixes #25497.

Instead of different wait queues per futex, this solution uses a
single wait queue for all threads waiting on any futex. The futex
address is stored in the thread structure. On wake, the kernel
walks through the queue and wakes either the highest priority or
all threads waiting on the specified futex address.

This is more lightweight than #42087 and more efficient for smaller
numbers of threads, but does not scale well to large numbers of
threads waiting on different futexes.

Add a test for the correct order when waking only one thread.

Signed-off-by: Christoph Busold <cbusold@qti.qualcomm.com>
2026-09-04 21:45:07 -04:00
Flavio Ceolin
affa5d05d0 twister: reject whitespace in list values that name one item
Space-separated lists stopped being split in 714e193340, so "a b" is now
taken verbatim and silently matches nothing. Fail loudly for keys whose
members name a tag, platform, feature or toolchain. extra_args and
extra_configs are exempt: their Kconfig values may contain spaces.

Signed-off-by: Flavio Ceolin <flavio@hubble.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-03 18:48:41 -04:00
Benjamin Cabé
d2bc22053b scripts: twister: test the ccache environment setup
Cover the four cases of TwisterEnv._setup_ccache(): the variables it
sets for a normal run, the two settings it leaves alone when they are
already in the environment, and the coverage build it skips.

os.environ is patched for the duration so the test neither depends on
nor leaks ccache settings.

Assisted-by: Claude:opus-5
Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
2026-09-03 18:48:33 -04:00
Benjamin Cabé
c87ad3e8ac scripts: twister: leave ccache alone for coverage builds
CCACHE_BASEDIR makes ccache rewrite absolute paths below the output
directory into relative ones in the command line it actually runs, so
the include path for the generated headers loses the build directory
and they are recorded relative to it in the .gcno. gcovr resolves them
from neither the object directory nor the source root, and the run
fails with "GCOVR failed with 64".

Skipping the optimization for coverage builds costs nothing: ccache
hashes the absolute object and .gcda paths whenever it generates
coverage data, so objects were never shared between build directories
there anyway. sloppiness=gcno_cwd does not change that; it only drops
the separate hashing of the working directory.

Fixes #117813

Assisted-by: Claude:opus-5
Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
2026-09-03 18:48:33 -04:00
Jamie McCrae
bf695aeb1e scripts: ci: check_compliance: Fold bracket in KeepSorted
Adds a line being a bracket to the allowances for folding, this
allows CMake lists to be used in sorting without it erroring out
that the bracket is unsorted (thinking it is a unique element in
the list)

Signed-off-by: Jamie McCrae <jamie.mccrae@nordicsemi.no>
2026-09-03 16:28:21 +02:00
Alberto Escolar Piedras
10f4d99695 requirements: install reuse with the custom_properties API
Since 7235648f39
check_compliance LicenseAndCopyrightCheck needs reuse's custom_properties
API, which is not yet in a released package. Install it from the
reuse-tool repo as a temporary measure until a new release makes it to
PyPi.

Without this users who follow our getting started guide, or in general
install from this requirement file or with
`west packages pip --install`
won't be able to run this check locally, as
scripts/ci/check_compliance.py -m LicenseAndCopyrightCheck would fail with
  AttributeError: 'AnnotationsItem' object has no attribute
  'custom_properties'
error.

Users who already had installed reuse, will need to remove it first with
`pip uninstall -y reuse`
as both the previous official version and this new version report the same
version (6.2.0).

Note this commit is just pointing to the same version which other
requirement files modified in PR 113130 already point to.

Signed-off-by: Alberto Escolar Piedras <alberto.escolar.piedras@nordicsemi.no>
2026-09-02 15:30:03 +02:00
Anas Nashif
1d93fe52d6 twister: sidecars: check host readiness at test-plan time
A sidecar could only discover a missing host tool in setup(), just
before executing the test image. The virtiofs sidecar then skipped
the instance at run time and logged a warning on every host without
a virtiofsd binary, which is noise on CI runners where the daemon is
simply not installed.

Introduce Sidecar.host_ready(), consulted from check_runnable() on a
configured sidecar at test-plan time. When the host lacks what the
sidecar needs, the instance is demoted to build-only, exactly like a
platform whose simulator executable is not installed, instead of the
gap surfacing as a late skip plus a warning. The virtiofs sidecar
implements the hook by checking that a virtiofsd binary was resolved;
the setup() guard remains as a safety net for forced runs.

Document the new lifecycle step and add unit tests for host_ready()
and for its wiring in check_runnable().

Assisted-by: Claude:claude-fable-5
Signed-off-by: Anas Nashif <anas.nashif@intel.com>
2026-09-02 15:29:41 +02:00
Benjamin Cabé
fccede09b7 scripts: zspdx: enrich SBOM blob files with module.yml metadata
Zephyr modules declare their binary blobs in module.yml, including the
blob's download URL, version, description and expected sha256. Surface
that provenance in the SBOM for blob files picked up during the walk:
as a FileComment in SPDX 2.3 output and as comment/description on the
software_File in SPDX 3.0 output.

Also cross-check the computed sha256 against the declared one while
scanning, warning when a linked blob does not match what its module
declares.

Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
2026-09-02 15:28:29 +02:00
Benjamin Cabé
73c55889e0 scripts: zspdx: walker: include linked prebuilt libraries in SBOM
Vendor blobs (e.g. the STM32WBA BLE controller libraries or the ESP32
Wi-Fi/BT libraries) never appeared in the generated SBOM: the CMake
codemodel only expresses libraries built by other targets, and prebuilt
libraries only show up on the final link command line.

Resolve each linked target's link command fragments instead: path
fragments are used directly (libraries linked as imported targets, as
hal_stm32 does) and -lNAME flags are resolved against the -L search
directories (as hal_espressif does). Resolved libraries outside the
build directory are attributed to their owning component and get a
STATIC_LINK relationship from the target's build product.

Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
2026-09-02 15:28:29 +02:00
Alberto Escolar Piedras
65ae11bf50 native_simulator: Get latest from upstream
Align with native_simulator's upstream main
38c1844c820760503463e63214b3a39783543243

Which includes:
38c1844 native irq_ctrl: Add is_pending API

Signed-off-by: Alberto Escolar Piedras <alberto.escolar.piedras@nordicsemi.no>
2026-08-31 15:11:39 -04:00
Benjamin Cabé
a96e3d8fc6 scripts: zephyr_module: move the module metadata schema to its own file
The JSON schema that validates zephyr/module.yml was a 130-line YAML
string embedded in zephyr_module.py, where it is easy to miss and reads
without highlighting or yamllint.

Move it to scripts/schemas/module-schema.yaml, next to the board, soc
and shield schemas, and load it the way list_boards.py loads its own.
The validation content is unchanged; the file gains the $id, title and
description that the sibling schemas carry, and is listed under the same
maintainer area as the module code that reads it.

Assisted-by: Claude:opus-5
Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
2026-08-31 07:01:14 -04:00
Benjamin Cabé
2c1264e73b cmake: remove deprecated ZephyrUnittest CMake package
The ZephyrUnittest package has printed a deprecation warning since
Zephyr 3.1, when it was replaced by the unittest component of the
Zephyr package: find_package(Zephyr COMPONENTS unittest). Remove the
package files, stop registering the package in west zephyr-export, and
drop the compatibility branch from ZephyrConfig.cmake.

Stale ZephyrUnittest entries in the CMake user package registry are
harmless: find_package(ZephyrUnittest) now simply fails to locate a
usable package instead of loading the compatibility shim.

Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
Assisted-by: Claude:fable-5
2026-08-31 07:00:13 -04:00
Alberto Escolar Piedras
36d4671a7e native_simulator: Get latest from upstream
Align with native_simulator's upstream main
eff1949a87a312928903b533e367bf7b62d382ec

Which includes:
eff1949 native: hw_timer: Add one shot API for the ticker

Signed-off-by: Alberto Escolar Piedras <alberto.escolar.piedras@nordicsemi.no>
2026-08-31 07:00:01 -04:00
Jeewoong Kim
c12c6b05e2 scripts: ci: fix BoilerplateFilter line matching
BoilerplateFilter uses a partial regular expression match when
classifying changed lines. This can cause substantive lines beginning
with comment delimiter characters, such as #define directives, to be
classified as boilerplate and consumed.

Match the complete changed line instead, while preserving support for
comment-prefixed SPDX and copyright lines.

Add regression coverage for delimiter-prefixed substantive changes and
verify that such files are not consumed.

Assisted-by: ChatGPT:GPT-5.6 Sol
Signed-off-by: Jeewoong Kim <dnd414@gmail.com>
2026-08-31 06:59:49 -04:00
Benjamin Cabé
4564d775ab scripts: ci: check_compliance: run checks in parallel by default
Run the compliance checks in parallel by default, one worker per CPU.
Pass -p 1 to get the old sequential behavior.

Assisted-by: Claude:opus-5
Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
2026-08-30 16:47:00 -04:00
Pieter De Gendt
f008ab3b23 west: blobs: verify the checksum of each downloaded URL
A server can answer a blob download with a success status but a bogus
payload, for example redirecting a raw file request for a missing
repository to its sign-in page with a 200 status. Such a download passed
the fetch step and made 'west blobs fetch' stop at the first URL,
only to fail the checksum verification afterwards, without ever trying
the remaining fallback URLs.

Verify the SHA-256 digest of each download inside the URL loop and
treat a mismatch like a failed download, so the next URL is tried.
Success and failures are reported where they happen, returning early
on the first verified download. If every URL yields a mismatch the
last download is kept, preserving the detailed error message of the
final verification step.

Assisted-by: Claude:claude-fable-5
Signed-off-by: Pieter De Gendt <pieter.degendt@basalte.be>
2026-08-28 15:32:22 -04:00
Benjamin Cabé
d33000ddf4 scripts: twister: let ccache reuse objects across test build directories
Twister builds every test in its own directory, and ccache keys on that
directory: it appears in the compiler command line, and in the hash that
keeps debug info apart because Zephyr always builds with -g. An object
compiled for one test is therefore never reused by another.

Set base_dir and hash_dir for the builds twister spawns. Building 121
qemu_x86 configurations from an empty cache, cache hits go from 1.5% to
70% and wall time from 727 s to 488 s. The gain grows with the number of
tests built, as more of them find an object a sibling already compiled.

Anything already set in the environment is left alone. A reused object
records the build directory it was first compiled in, so its debug info
points there; Zephyr passes absolute source paths, so in practice only
files generated into the build directory are affected.

Assisted-by: Claude Code:claude-opus-5
Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
2026-08-28 15:31:03 -04:00
Benjamin Cabé
882582e904 scripts: ci: check_compliance: explain KconfigHWMv2 undefined symbols
The KconfigHWMv2 check loads only the board and SoC Kconfig trees, so
references to symbols defined elsewhere in Zephyr surface as bare
kconfiglib "undefined symbol" warnings, which do not make the root
cause (a misplaced symbol reference) clear to developers.

Append probable causes and a fix suggestion to the failure message of
that check, and link its documentation to the board porting guide.

Fixes: #69838

Assisted-by: Claude:claude-fable-5
Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
2026-08-28 06:46:19 -04:00
Benjamin Cabé
7235648f39 ci: check_compliance: require an exception for non-Apache-2.0 files
Keep the generated licensing page complete: a non-Apache-2.0 file added to
the main tree without a documented exception (a REUSE.toml annotation with
a Zephyr-Description key) is now flagged. CC-BY-4.0 is accepted without an
exception on .rst sources only, per the project charter.

Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
Assisted-by: Claude:opus-4.8
2026-08-28 06:45:57 -04:00
Benjamin Cabé
3afe97fee4 scripts: list files with an undocumented license
Spotting a file that carries a license other than the project defaults
(Apache-2.0, or CC-BY-4.0 for docs) and is not yet described in REUSE.toml
meant eyeballing raw "reuse lint" output. Add a small helper, built on the
reuse library, that reports exactly those files, as a CLI and as an
importable function reused by the docs licensing page and the CI compliance
check.

Identifiers that reuse extracts from tooling source or malformed comment
banners but that SPDX does not recognize are ignored, so the report only
lists real licenses.

Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
Assisted-by: Claude:opus-4.8
2026-08-28 06:45:57 -04:00