# Public API reference — 0.1.0 stable surface The application-facing API and its **stability contract** for the 0.1.0 development release. This is the single reference for what an app may call and what it may rely on; the authoritative per-symbol contract lives in the headers themselves (`kernel/*.h`, `hal/*.h`), which this doc indexes. ## How to read this **Header tiers** | Tier | Headers | Meaning | |---|---|---| | **A — application API** | `tk_kernel.h`, `tk_sem.h`, `tk_mutex.h`, `tk_cond.h`, `tk_spinlock.h`, `tk_seqlock.h`, `tk_status.h`, `tk_types.h`, `tk_time.h` + `hal/{tk_console,tk_board,tk_dio,tk_dio_irq,tk_uart,tk_port,tk_mcu}.h` | what an app includes | | **B — tooling / observability** | `tk_trace.h`, `tk_det.h` | trace tools + a DET hook; the *interface* is stable, details experimental | | **Internal — NOT the API** | `tk_kernel_sync.h` (Tier-C extension for library authors), `tk_stack.h` (placeholder), the `*_internal.h` / `*_port.h` | live in `kernel/` but carry a "not the application API" banner | **Annotation tags** (in the headers) - `[rt]` — callable at runtime from a thread, including an unprivileged one (traps through the syscall path). - `[setup]` — privileged/setup-only (before `tk_kernel_start`, or from a system thread). - `[override]` — a **weak seam you provide** (app or board), not a call-in API; the kernel calls it. - `[experimental]` — signature or semantics may still change; **NOT frozen** for 0.1.0. **Stability:** everything below is **STABLE (frozen for 0.1.0)** unless marked `[experimental]`. Frozen means it will not change without a deprecation. The current experimental set is the **WORLD** security axis, the **INSTANCE supervisor-fence** override seams, and the **thread-introspection** snapshot — surfaces whose backing feature is not yet proven on a shipping board. --- ## Threads (`tk_kernel.h`) | Symbol | Tag | Contract | |---|---|---| | `tk_thread_create(fn, arg, stack, cells, prio) → tk_thread_t*` | `[setup/rt]` | positional create; NULL if the pool is full | | `tk_thread_create_in(k, …, out) → tk_thread_t*` | `[setup]` | create into a specific instance | | `tk_thread_spawn(&t, &attr, fn, arg) → tk_status_t` | `[setup]` | attr create (pthread_create shape) | | `tk_thread_spawn_in(k, &t, &attr, fn, arg) → tk_status_t` | `[setup]` | attr create into an instance | | `tk_thread_attr_init / setstack / setpriority / setdetachstate` | `[setup]` | attribute builders (pthread_attr_* shape) | | `tk_thread_yield()` · `tk_thread_sleep_ms(ms)` · `tk_sleep_ms(ms)` | `[rt]` | yield / sleep (the last is the one aliased short form) | | `tk_thread_exit(rv)` · `tk_thread_join(t, &rv)` · `tk_thread_detach(t)` | `[rt]` | exit (noreturn) / join+reap / detach | | `tk_thread_self()` · `tk_thread_id(t)` · `tk_thread_kernel(t)` | `[rt]` | own handle / stable id / owning instance | | `tk_thread_set_quantum / set_privileged / set_affinity / pin / set_deadline` | `[setup]` | per-thread config (affinity `#if TK_FEAT_AFFINITY`, deadline `#if TK_CONFIG_ENABLE_EDF`) | | `tk_thread_set_name(t, name)` | `[setup]` | attach a name (no-op without a trace/introspect build) | | `tk_kernel_thread_snapshot(out, max)` · `_in` · `struct tk_thread_info` | `[rt]` `[experimental]` | ps/top snapshot; record shape may change | **Types:** `tk_thread_fn = void*(*)(void*)` (pthread-shaped), `tk_thread_attr_t`, `enum tk_thread_state`, `enum tk_thread_detachstate`. **Constants:** `TK_PRIO_IDLE/MIN/MAX`, `TK_CORE(n)`, `TK_THREAD_STACK(name, size)`. ## Kernel lifecycle & instances (`tk_kernel.h`) | Symbol | Tag | Contract | |---|---|---| | `tk_kernel_init()` · `tk_kernel_start()` | `[setup]` | init once; enter the scheduler (no return on a switching port) | | `tk_kernel_set_idle_hook / set_sched_policy / set_preempt_mode` (+ `_in`) | `[setup]` | kernel config (bare = default instance) | | `tk_kernel_define(owned_cores, name, out) → tk_kernel_t*` | `[setup]` | declare an AMP/SMP-subset island | | `tk_kernel_set_ram(k, base, size)` · `tk_kernel_set_trusted(k)` | `[setup]` | island private arena (C3-B) / trusted-monitor escape hatch | | `tk_kernel_default / find / count / at` | `[setup]` | instance-handle ergonomics | | `tk_kernel_self()` · `tk_kernel_name(k)` · `tk_kernel_owned_cores(k)` | `[rt]` | this-core instance / name / core mask | | `tk_kernel_isolation()` | `[rt]` | the HW isolation boundary this build enforces | | `tk_kernel_liveness_check(hard, soft)` · `tk_kernel_now_ms_in(k)` | `[rt]` | cross-island stall poll / a specific instance's clock | | **WORLD axis:** `tk_kernel_set_world / world / launch_secondary`, `tk_world_t`, `tk_fallback_t` | `[experimental]` | TrustZone-AMP security attribution — no shipping board realizes it yet | | **Override seams:** `tk_kernel_on_stall`, `tk_watchdog_kick`, `tk_core_unclaimed`, `tk_instance_fence_reject`, `board_instance_fence_apply`, `board_world_protect`, `board_core_release` | `[override]` | weak; you/the board provide them | ## Synchronization | Header | Stable surface | |---|---| | `tk_mutex.h` | `tk_mutex_create(_in)`, `tk_mutex_init(&h, &attr)` (pthread_mutex_init shape), `tk_mutex_lock/unlock/lock_timeout`, `tk_mutexattr_init/settype/setprotocol`; `TK_MUTEX_{NORMAL,RECURSIVE,ERRORCHECK}`, `TK_MUTEX_PRIO_{NONE,INHERIT}` | | `tk_sem.h` | `tk_sem_create(_in)`, `tk_sem_pend/post/pend_timeout`, `tk_sem_set_name`; `TK_SEM_INVALID` | | `tk_cond.h` | `tk_cond_create(_in)`, `tk_cond_wait/wait_timeout/signal/broadcast`; `TK_COND_INVALID` | | `tk_spinlock.h` | `tk_spin_init/lock/unlock/trylock` (SMP, `static inline`, value-typed key) | | `tk_seqlock.h` | `tk_seq_init/write_begin/write_end/read_begin/read_retry` (read-mostly) | Handles (`tk_sem_t` / `tk_mutex_t` / `tk_cond_t`) are opaque `int16_t` into a static kernel pool; `[rt]` for the operate calls, `[setup]` for create/init/set_name. ## Time (`tk_time.h`) `tk_time_init()` `[setup]`; `tk_time_ms()` · `tk_time_us()` · `tk_kernel_now_ms()` `[rt]`. `tk_kernel_now_ms` is a second name for `tk_time_ms` kept for the scheduler/EDF timebase. ## HAL (`hal/*.h`) Minimal, stable contract (a status-returning / UART-RX layer is a compatible future add): `tk_board_init`; `tk_console_init` + `tk_print` / `tk_print_u32` (+ weak `tk_console_lock/unlock`); `tk_dio_read/write/flip` (channel + pin) with `TK_DIO_LOW/HIGH`; `tk_dio_irq_*` (edge → callback); `tk_uart_init/write/setup`; `tk_port_init/config_pin` with `tk_dir_t`/`tk_pull_t`; `tk_mcu_init` / `tk_mcu_clock_hz`. The HAL uses its own `tk_*_channel_t` id types and does not carry the `[rt]`/`[setup]` scheme (that vocabulary is kernel-only). ## Shared types `tk_status.h` — `tk_status_t` `{TK_OK, TK_ERR_PARAM, TK_ERR_BUSY, TK_ERR_STATE, TK_ERR_TIMEOUT, TK_ERR_UNSUPPORTED, TK_ERR}`. `tk_types.h` — `tk_stack_cell_t` (the addressable stack cell, ADR 0001). ## POSIX / pthreads The threads + mutex + cond surface is **pthread-shaped** (not compliant). An opt-in shim [`compat/pthread.h`](../../compat/pthread.h) maps `pthread_{create,join,detach,exit,self,equal}`, `pthread_attr_*`, `pthread_mutex_*`/`mutexattr`, `pthread_cond_*` onto `tk_*`; the demo `examples/pthread_api` proves it. Full analysis: [`docs/evaluation/standards-api-ergonomics.md`](../evaluation/standards-api-ergonomics.md). ## Compile-time configuration Knobs (`TK_CONFIG_*`) and derived capability flags (`TK_FEAT_*`, `TK_ISOLATION_*`, `TK_ARCH_*`) are transitively public through `tk_kernel.h`. Each carries a labelled contract block in [`kernel/tk_config.h`](../../kernel/tk_config.h) — the single source of truth for values, defaults, requirements, and effects. ## Naming notes (frozen for 0.1.0) - Three construction verbs are deliberate, not inconsistent: **`create`** (positional convenience), **`spawn`** (attr form, pthread_create shape), **`define`** (a kernel instance). - `tk_sleep_ms` is the single intentional short alias (ADR 0002 §8); `yield`/`exit`/`join` keep `tk_thread_`. - The `_in` suffix consistently marks the instance-targeted twin of a default-instance call.