Skip to content

Releases: uLipe/ulmk_microkernel

ulmk 0.3.1: Component layout cleanup for a leaner kernel and clear

Choose a tag to compare

@uLipe uLipe released this 27 Jul 13:55

Companion tags (same version): ulmk_apps 0.3.1 · ulmk_boards 0.3.1

Changes

  • Kernel builtins reduced to hello_world only
  • ping_pong moved to ulmk_apps as a standalone ROOT_THREAD demo
  • Silicon HIL certs nested under ulmk_apps/silicon/ (recursive CMake aggregator)
  • Removed unused board_leds glue and tricore_asclin
  • dev.py / CI / docs updated for separate hello / ping_pong images

Fix

  • TriCore silicon_pool_exhaust: handle trackers placed in .user_bss so the ISR stack no longer straddles _small_data_ at RAM+0x8000

Validation

  • TC275 Lite silicon HIL suite (including silicon_pool_exhaust)

ulmk 0.3.0: public release

Choose a tag to compare

@uLipe uLipe released this 21 Jul 13:40

Kernel release with a hierarchical timing wheel, board timer migration onto the arch tick, and continued SMP scale work (RISC-V ×4 QEMU + TriCore 3-core silicon path from the 0.2.x line).

Companion tags (same version): ulmk_apps 0.3.0 · ulmk_boards 0.3.0

Highlights

Timing wheel

  • New kernel time subsystem (kernel/time/) — hierarchical timer wheel driven by the arch periodic tick
  • Public API:
    • ulmk_sleep_ms() / ulmk_sleep_cancel()
    • ulmk_ep_call_timeout() / ulmk_notif_wait_timeout()
    • ulmk_tick_start() — board bring-up arms the kernel tick once
  • QEMU board timers (TriCore / RISC-V / ARMv7-M / ARMv8-M) are thin wrappers over ulmk_sleep_ms; STM/CLINT/SysTick stay owned by the arch tick (no userspace compare-match sleep server)
  • Unit + SDK coverage: tests/timer_unit, sdk_suite/sleep, sleep_cancel, ipc_timeout, notif_timeout

SMP scale (since 0.2.0)

  • RISC-V: boards/qemu_riscv_virt_smp4 + SDK/CI jobs for 4-hart scale (smp_* / smp4_*)
  • TriCore: CPU2 secondary bring-up path aligned with TC275 3-core HIL

Fixes / hardening

  • TriCore tick_ack preserves SRC SRPN/TOS (no longer reclaiming a userspace bind_hw on STM0 SR0) — unblocks TC275 silicon_irq_stress with kernel-owned tick
  • Linker: .user_data capture for orphan SDK .data under user MPU windows (ARMv8-M)

Compatibility notes

  • Board code that slept via a private STM0 CMP/notif server should call ulmk_tick_start() at bring-up and use ulmk_sleep_ms() / board_timer_sleep_* thin wrappers
  • Soft-IRQ tests on real AURIX must not rely on arbitrary SRC SETR from userspace; prefer a real event source (e.g. STM compare) with a non-tick SRPN

Validation

  • QEMU unit + e2e UP: TriCore, RISC-V, MPS2 AN500, MPS2 AN505
  • QEMU e2e SMP / SMP×4: RISC-V
  • Silicon TC275 Lite HIL: silicon suite + board components (UP/SMP); silicon_irq_stress PASS on /dev/ttyUSB1

ulmk 0.2.0 — Second public release: SMP support and more.

Choose a tag to compare

@uLipe uLipe released this 15 Jul 20:46

ulmk 0.2.0

Second public release. Same three-repo companion set as 0.1.x — tag all of:

Repo Tag
ulmk_microkernel 0.2.0
ulmk_apps 0.2.0
ulmk_boards 0.2.0

Use matching tags together for HIL / board builds.


Highlights

SMP (RISC-V QEMU + TriCore TC275)

  • Per-CPU runqueues, klocks, and ENABLE_SMP configuration
  • Thread affinity (attr.cpu / ulmk_cpu_id()), lazy secondary context, deferred IPI reschedule
  • Secondary bring-up on RISC-V virt and AURIX TC275 (CPU1)
  • SMP-safe IPC / notification paths (lock ordering; flood-safe notif)
  • SDK suite: smp_smoke, smp_affinity, smp_ipc_cross, smp_stress, smp_vs_up
  • CI: RISC-V e2e with --include-smp

Syscall WCET (silicon-ready under SMP)

  • Per-CPU WCET sample slots (global slot no longer races across cores)
  • ulmk_wcet_bind() — private sample buffer per measuring thread
  • Secondary cores enable cycle counters at bring-up
  • Builds on 0.1.1 WCET/hot-path work (pure syscall WCET, deferred resched, MPU skip, lean CSA)

Silicon / board companions

  • ulmk_apps: silicon suite zero-inits / pins cpu=0; WCET bind in silicon_wcet; silicon_irq_stress uses STM0 CMP0/SR0 (CMP1→SR1 does not assert SRR on this kit); new silicon_smp_smoke
  • ulmk_boards/tc275_lite: CPU1 memory/OpenOCD/HIL wiring, hil-silicon-smp-smoke.sh, smp_can_demo, wcet_compare.py

Supported platforms (regression matrix for this tag)

Target Unit SDK e2e Baseline hello+ping Notes
QEMU TriCore qemu_tc3xx ✓ UP
QEMU RISC-V qemu_riscv_virt ✓ UP + SMP ✓ UP + SMP SMP CI arch
QEMU ARMv7-M qemu_mps2_an500 ✓ UP
QEMU ARMv8-M qemu_mps2_an505 ✓ UP
Silicon TC275 lite ✓ UP + SMP silicon_* board comps UP+SMP Full HIL green at tag

Breaking / API notes

  • New syscalls: ULMK_SYS_CPU_ID (21), ULMK_SYS_WCET_BIND (22)
  • ulmk_thread_attr_t.cpu — set explicitly (or rely on kernel clamp to 0 when !SMP); uninitialized stack garbage breaks create/spawn under SMP
  • Apps measuring WCET under SMP should call ulmk_wcet_bind() before sampling

Upgrade from 0.1.1

  1. Update the three repos / tags to 0.2.0 in lockstep
  2. Rebuild SDK cache if linking sdk_suite (rm -rf tests/sdk_suite/_sdk_cache or let dev.py refresh)
  3. For TC275 SMP images: use --enable-smp and the SMP OpenOCD / HIL scripts from ulmk_boards

Changelog (kernel, since 0.1.1)

  • kernel: add SMP foundation with per-CPU runqueues and affinity
  • syscall: use per-CPU WCET slots and ulmk_wcet_bind
  • tests/ci: add RISC-V SMP sdk suite cases and CI job

ulmk 0.1.1 - Patch release focused on scheduling/syscall hot-path cost and cleaner trap/ISR exit semantics

Choose a tag to compare

@uLipe uLipe released this 15 Jul 01:45

Highlights

Deferred context switch (trap / ISR exit)

Syscall and IRQ handlers now only enqueue/block and set needs_resched. The
actual switch runs once in ulmk_sched_trap_dispatch on the way back to
userspace”.

  • Removes mid-handler handoff / ctx_switch from IPC and notif wait paths
  • Return codes for blocked callers are resolved after dispatch
    (ulmk_kern_syscall_ret_resolve)
  • Syscall WCET metrics no longer fold scheduler switch cost into the call wall
    time (blk gone from those samples)

Hot-path trimming

  • TriCore CSA path: drop mid-switch CALL to post-save helpers and redundant
    dual isync on the lean context-switch / vector path
  • MPU / IRQ: skip redundant MPU reprograms and nested irq_save where the
    kernel/ISR gateway already masks IRQs
  • IPC: envelope staging by pointer, rendezvous handoff prep + stack MPU skip,
    IRQ mask held across switch return where needed

Commits since 0.1.0

  • arch: skip redundant MPU reprograms and nested irq_save
  • kernel: unify sched switch and expose pure syscall WCET
  • ipc: cut ep rendezvous cost via handoff and stack MPU skip
  • ipc: stage ep envelopes by pointer, keep irq mask on switch return
  • arch/tricore: lean CSA path — drop mid-switch CALL and dual isync
  • kernel: defer context switch to trap/ISR exit
  • kernel: drop nested irq_save in IRQ binding paths

Compatibility

  • Public syscall / userspace API unchanged for apps and board components
  • Root-thread / boot model unchanged

Validation (release gate)

  • Unit + full SDK suite (tests unit / tests e2e) on TriCore QEMU,
    qemu_riscv_virt, qemu_mps2_an500, qemu_mps2_an505
  • Baseline demo hello_world + ping_pong console output on all four boards
  • Full silicon cert set on TC275 Lite (silicon_* apps / HIL scripts)
  • Board component smoke on TC275 (except gpio_led_notify): ADC, blinky,
    CAN loopback, I2C scanner, PWM LED — flash OK + console output

ulmk CI test report

Cases with results: 28

1. Execution results

Case Host (unit) TriCore RISC-V ARM
atomic_unit PASS n/a n/a n/a
ipc_unit PASS n/a n/a n/a
mem_unit PASS n/a n/a n/a
sched_unit PASS n/a n/a n/a
sdk_suite/abi_smoke n/a PASS PASS PASS
sdk_suite/arch_whitebox/ctx_early_tricore n/a PASS n/a n/a
sdk_suite/atomic_stress n/a PASS PASS PASS
sdk_suite/boot_bss n/a PASS PASS PASS
sdk_suite/cap_neg n/a PASS PASS PASS
sdk_suite/ctx_switch n/a PASS PASS PASS
sdk_suite/destroy_waiters n/a PASS PASS PASS
sdk_suite/fault_policy n/a PASS PASS PASS
sdk_suite/ipc n/a PASS PASS PASS
sdk_suite/ipc_pi n/a PASS PASS PASS
sdk_suite/irq_stress n/a PASS PASS PASS
sdk_suite/irq_sw n/a PASS PASS PASS
sdk_suite/kill_rendezvous n/a PASS PASS PASS
sdk_suite/mem_grant n/a PASS PASS PASS
sdk_suite/mem_heap n/a PASS PASS PASS
sdk_suite/mem_isolation n/a PASS PASS PASS
sdk_suite/pool_exhaust n/a PASS PASS PASS
sdk_suite/preempt n/a PASS PASS PASS
sdk_suite/recv_or_notif_race n/a PASS PASS PASS
sdk_suite/resource_leak n/a PASS PASS PASS
sdk_suite/sched_order n/a PASS PASS PASS
sdk_suite/sleep_timer n/a PASS PASS PASS
sdk_suite/thread_lifecycle n/a PASS PASS PASS
thread_unit PASS n/a n/a n/a

Values: PASS | FAIL | PARTIAL | SKIP | n/a. ARM aggregates AN500+AN505 (mixed → PARTIAL).

2. Coverage levels

Area TriCore RISC-V ARM Notes
thread.basic covered covered covered
sched.order covered covered covered
ipc.basic covered covered covered
ipc.priority_inherit covered covered covered silicon_ipc_pi + sdk_suite/ipc_pi
mem.heap covered covered covered
mem.isolation covered covered partial ARM mem_grant livelock risk
cap.eperm_neg covered covered covered silicon_cap_neg HIL PASS; sdk_suite/cap_neg
mem.grant covered covered covered silicon_mem_grant HIL PASS; sdk_suite/mem_grant
fault.policy covered covered covered userspace MPU fault kills thread; system continues
irq.sw covered covered covered
irq.stress covered covered covered silicon_irq_stress HIL + sdk_suite/irq_stress
wcet.syscall_o1 covered n/a n/a silicon_wcet HIL only (ULMK_CONFIG_SYSCALL_WCET); QEMU out of scope
proc.mgmt missing missing missing out of scope this cycle — process model TBD; GRANT_CAP is ulmk_cap_grant
atomic covered covered covered
sleep.timer covered covered covered
boot.bss covered covered covered
ctx.switch covered covered covered
resource.leak covered covered covered
abi.smoke covered covered covered
arch.ctx_early_tricore covered missing missing arch-only
ipc.destroy_waiters missing missing missing silicon_destroy_waiters + sdk_suite/destroy_waiters
ipc.kill_rendezvous missing missing missing silicon_kill_rendezvous + sdk_suite/kill_rendezvous
pool.exhaust missing missing missing silicon_pool_exhaust + sdk_suite/pool_exhaust
ipc.recv_or_notif_race missing missing missing silicon_recv_or_notif_race + sdk_suite/recv_or_notif_race

Values: covered | partial | missing (from tools/coverage_manifest.yaml, independent of run PASS/FAIL).

Coverage summary

Arch covered partial missing
tricore 19 0 5
riscv 17 0 7
arm 16 1 7

Upgrade notes

From 0.1.0: rebuild kernel / SDK artefacts; no application source changes required
for the deferred-reschedule behaviour. Builds with ULMK_CONFIG_SYSCALL_WCET
should treat samples as in-kernel cost, not full blocked RTT.

ulmk 0.1.0 — First public release

Choose a tag to compare

@uLipe uLipe released this 14 Jul 02:36

The first tagged release of ulmk: a small, seL4-inspired microkernel for microcontroller-class targets. Mechanism in the kernel, policy in userspace, one ELF with MPU/PMP isolation.

Supported platforms

Arch Target Status
TriCore QEMU TC3xx + Infineon AURIX TC275 Lite (HIL) Primary
RISC-V RV32IMAC, QEMU virt CI green
ARM Cortex-M7 (mps2-an500) / Cortex-M33 (mps2-an505) CI green

Highlights

  • Synchronous IPC with priority inheritance
  • Capability-oriented syscalls (threads, endpoints, notifications, memory, IRQ bind)
  • O(1) bitmap scheduler, root-thread boot model
  • Component build (tools/dev.py) and distributable SDK packaging
  • Optional syscall WCET cycle slot (ULMK_CONFIG_SYSCALL_WCET)

Validation (acceptance: zero FAIL)

  • Host unit tests
  • Full sdk_suite black-box matrix on TriCore, RISC-V, and both ARM QEMU boards
  • Baseline demos (hello_world + ping_pong) on all QEMU boards
  • Silicon HIL cert set on TC275 Lite (unit, e2e, stress, WCET, IRQ stress, PI, fault/cap/mem, waiter lifecycle, …)

Companion repositories

Use matching tag 0.1.0:

  • ulmk_apps — userspace apps + silicon cert components
  • ulmk_boards — TC275 Lite BSP, drivers, HIL shims

Getting started

git clone https://github.com/uLipe/ulmk_microkernel.git
cd ulmk_microkernel
git checkout 0.1.0
python3 tools/dev.py   # builds the multi-arch Docker image on first run
python3 tools/dev.py components enable hello_world ping_pong
python3 tools/dev.py build qemu

ulmk CI test report

Cases with results: 28

1. Execution results

Case Host (unit) TriCore RISC-V ARM
atomic_unit PASS n/a n/a n/a
ipc_unit PASS n/a n/a n/a
mem_unit PASS n/a n/a n/a
sched_unit PASS n/a n/a n/a
sdk_suite/abi_smoke n/a PASS PASS PASS
sdk_suite/arch_whitebox/ctx_early_tricore n/a PASS n/a n/a
sdk_suite/atomic_stress n/a PASS PASS PASS
sdk_suite/boot_bss n/a PASS PASS PASS
sdk_suite/cap_neg n/a PASS PASS PASS
sdk_suite/ctx_switch n/a PASS PASS PASS
sdk_suite/destroy_waiters n/a PASS PASS PASS
sdk_suite/fault_policy n/a PASS PASS PASS
sdk_suite/ipc n/a PASS PASS PASS
sdk_suite/ipc_pi n/a PASS PASS PASS
sdk_suite/irq_stress n/a PASS PASS PASS
sdk_suite/irq_sw n/a PASS PASS PASS
sdk_suite/kill_rendezvous n/a PASS PASS PASS
sdk_suite/mem_grant n/a PASS PASS PASS
sdk_suite/mem_heap n/a PASS PASS PASS
sdk_suite/mem_isolation n/a PASS PASS PASS
sdk_suite/pool_exhaust n/a PASS PASS PASS
sdk_suite/preempt n/a PASS PASS PASS
sdk_suite/recv_or_notif_race n/a PASS PASS PASS
sdk_suite/resource_leak n/a PASS PASS PASS
sdk_suite/sched_order n/a PASS PASS PASS
sdk_suite/sleep_timer n/a PASS PASS PASS
sdk_suite/thread_lifecycle n/a PASS PASS PASS
thread_unit PASS n/a n/a n/a

Values: PASS | FAIL | PARTIAL | SKIP | n/a. ARM aggregates AN500+AN505 (mixed → PARTIAL).

2. Coverage levels

Area TriCore RISC-V ARM Notes
thread.basic covered covered covered
sched.order covered covered covered
ipc.basic covered covered covered
ipc.priority_inherit covered covered covered silicon_ipc_pi + sdk_suite/ipc_pi
mem.heap covered covered covered
mem.isolation covered covered partial ARM mem_grant livelock risk
cap.eperm_neg covered covered covered silicon_cap_neg HIL PASS; sdk_suite/cap_neg
mem.grant covered covered covered silicon_mem_grant HIL PASS; sdk_suite/mem_grant
fault.policy covered covered covered userspace MPU fault kills thread; system continues
irq.sw covered covered covered
irq.stress covered covered covered silicon_irq_stress HIL + sdk_suite/irq_stress
wcet.syscall_o1 covered n/a n/a silicon_wcet HIL only (ULMK_CONFIG_SYSCALL_WCET); QEMU out of scope
proc.mgmt missing missing missing out of scope this cycle — process model TBD; GRANT_CAP is ulmk_cap_grant
atomic covered covered covered
sleep.timer covered covered covered
boot.bss covered covered covered
ctx.switch covered covered covered
resource.leak covered covered covered
abi.smoke covered covered covered
arch.ctx_early_tricore covered missing missing arch-only
ipc.destroy_waiters missing missing missing silicon_destroy_waiters + sdk_suite/destroy_waiters
ipc.kill_rendezvous missing missing missing silicon_kill_rendezvous + sdk_suite/kill_rendezvous
pool.exhaust missing missing missing silicon_pool_exhaust + sdk_suite/pool_exhaust
ipc.recv_or_notif_race missing missing missing silicon_recv_or_notif_race + sdk_suite/recv_or_notif_race

Values: covered | partial | missing (from tools/coverage_manifest.yaml, independent of run PASS/FAIL).

Coverage summary

Arch covered partial missing
tricore 19 0 5
riscv 17 0 7
arm 16 1 7

Built for fun and learning — contributions and board ports welcome. :)