# Writing examples — naming & structure convention Every program under `examples/` follows this convention. It exists so a reader can tell, from the directory name alone, **what feature the example demonstrates, which architecture it needs, and which board** — while keeping examples as portable (and as un-suffixed) as possible. ## One example, one feature An example demonstrates exactly **one** feature, in the smallest self-contained way: *instantiate → use → done*. It is not a kitchen sink. If you find yourself showing two features, split into two examples. - No redundancy — if an existing example already covers the feature on a given target, don't add a near-duplicate. - Minimal — only the code needed to show the feature and prove it worked (a print, an LED, a fault). ## Directory naming The directory name **is the feature**: `examples/`. Add a suffix **only when necessary**, and only as much as necessary: | Form | When | Example | |---|---|---| | `examples/` | the feature/API is portable (the goal) | `threads`, `trace`, `watchdog`, `isolation` | | `examples/_` | the feature or its API is architecture-specific, **or** the same feature needs a separate demo per architecture | `fence_riscv`, `fence_tricore`, `unpriv_tricore` | | `examples/__` | the feature is board-specific **and** the arch alone doesn't identify the board needed | `fence_arm_v8m_frdm_mcxn947` | Rules: - **Portability first.** An arch/board suffix is the down-prioritized exception. Prefer writing a portable example; only lock it to an arch/board when the feature genuinely cannot be "just a demo." - **`` = the family, disambiguated only when needed.** Use the family (`arm`, `riscv`, `tricore`) when one demo covers it; add the sub-arch only to disambiguate multiple demos of the same feature (the three ARM supervisor-fence demos are `fence_arm_v7a`, `fence_arm_v8a`, `fence_arm_v8r` because the mechanism differs per profile; a single ARM-only demo is just `hardfault`). - **No `_demo` suffix** — it's redundant inside `examples/`. - The Makefile's `PROJECT :=` must equal the directory name. ### Worked examples - `threads` — bring up the kernel and spawn threads (portable). - `trace` — the trace ring API (portable). - `watchdog` — the watchdog API (portable). - `fence_arm_v7a` / `fence_riscv` / `fence_tricore` — the supervisor-fence API, one demo per mechanism. - `unpriv_tricore`, `csa_reclaim_tricore` — features currently demonstrated only on AURIX TriCore. When a portable version lands for other architectures, these remain the TriCore instances. ## Structure & comment style Keep the body a clear *instantiate → use → done* sequence. Step comments describe the step in plain words — **do not number them**: ```c /* Create the semaphore the producer will post. */ sem = tk_sem_create(0); /* Spawn the worker on its own stack. */ tk_thread_create(worker, NULL, stack, sizeof stack, TK_PRIO_MIN + 1u); ``` Not `/* 1. Create the semaphore */` — the numbering adds nothing and rots when steps change. The file header comment should open with `/main.c — ` and, where useful, a one-line build/run note (`make BOARD= flash`). ## Porting legacy examples The pre-reshape tree (`_legacy/examples/`) holds ~90 more demos (peripherals, crypto, secure-boot, more boards). They are ported **on demand, together with the API/HAL they exercise** — not ahead of it — and each is renamed to this convention when it lands. See `docs/readiness-1.0.0/dashboard.md` for what is planned.