nros platform-cffi
Canonical C ABI for porting the nros platform abstraction
Loading...
Searching...
No Matches
platform.h
Go to the documentation of this file.
1#ifndef NROS_PLATFORM_H
2#define NROS_PLATFORM_H
3
4#include <stdint.h>
5#include <stddef.h>
6#include <stdbool.h>
7
48/* ---- Platform capability defaults (RFC-0042 D2 / phase-241 B + C) ----
49 *
50 * Platform-*constant* capabilities. The single source of truth for a board's
51 * *variable* capabilities is its `nros-board.toml` `[board.capabilities]`, lowered
52 * to `-DNROS_PLATFORM_HAS_MALLOC` (etc.) by the build (phase-241 C.2). These
53 * blocks supply only the per-platform constants, and never override a `-D` the
54 * board already set (every `#define` is `#ifndef`-guarded).
55 *
56 * - `NROS_PLATFORM_HAS_MALLOC` gates the canonical `malloc`/`free` shim below.
57 * Absent → a TU using the nros-cpp heap containers fails to *compile* (not
58 * link) — the issue-0038 guard.
59 * - `NROS_PLATFORM_HAS_ATOMICS` is true on every supported target today.
60 *
61 * RTOS-config-derived capabilities are intentionally NOT defaulted here:
62 * - FreeRTOS heap ← `configSUPPORT_DYNAMIC_ALLOCATION` (FreeRTOSConfig.h),
63 * - Zephyr heap/mutex ← `CONFIG_HEAP_MEM_POOL_SIZE` / `CONFIG_MULTITHREADING`.
64 * Those boards declare `heap = true` in board.toml and the build lowers it to
65 * the Kconfig/FreeRTOSConfig knob, keeping the C view tied to the RTOS config.
66 */
67/* HAS_ATOMICS is a constant on every supported target. */
68#ifndef NROS_PLATFORM_HAS_ATOMICS
69# define NROS_PLATFORM_HAS_ATOMICS
70#endif
71
72/* HAS_MALLOC by platform. POSIX (and the POSIX-mapped hosted platforms: NuttX,
73 * ThreadX-linux, native) and the heap RTOSes (Zephyr, FreeRTOS) always run with
74 * an allocator under nros — the generator always configures the RTOS heap
75 * (`CONFIG_HEAP_MEM_POOL_SIZE`, `configSUPPORT_DYNAMIC_ALLOCATION`), and each
76 * declares `heap = true` in its `nros-board.toml`. They get the canonical
77 * malloc/free unconditionally here.
78 *
79 * Bare-metal / ThreadX-RV64 / ESP / custom do NOT default a heap: they opt in
80 * via the board.toml-derived `-DNROS_PLATFORM_HAS_MALLOC` (phase-241 C.2), so a
81 * genuinely heap-less board still fails to compile a heap container (the #38
82 * compile-gate). */
83/* Every hosted/RTOS platform has a heap (POSIX, Zephyr, FreeRTOS, ThreadX-linux,
84 * NuttX, and the default/unspecified case). This mirrors the retired nros-c
85 * dispatch, where any non-bare-metal platform fell through to `posix.h`'s
86 * unconditional malloc. Only bare-metal (incl. ThreadX-RV64 / ESP, which map to
87 * `NROS_PLATFORM_BAREMETAL`) withholds the heap and opts in via the
88 * board.toml-derived `-DNROS_PLATFORM_HAS_MALLOC` (phase-241 C.2 / the #38 gate). */
89#if !defined(NROS_PLATFORM_BAREMETAL)
90# ifndef NROS_PLATFORM_HAS_MALLOC
91# define NROS_PLATFORM_HAS_MALLOC
92# endif
93#endif
94
95#ifdef __cplusplus
96extern "C" {
97#endif
98
99/* ---- Return codes ----
100 *
101 * phase-364 W1 (RFC-0076 D3). This vocabulary was declared and used by NO
102 * port: 26 entry points returned a bare `int8_t` 0/-1, so "this platform
103 * never does this" and "this failed just now" were the same value.
104 *
105 * That distinction is not academic. A caller may cache `UNSUPPORTED` forever
106 * and MUST retry `NOMEM`: issue 0246 is a transient `pthread_create` failure
107 * on NuttX under load, and phase-359 W10's worker pool — unable to ask — caches
108 * every refusal, disabling a priority level for the process on what may have
109 * been a momentary shortage.
110 *
111 * `nros_platform_ret_t` is `int8_t` because that is the width the functions
112 * already return; it was `int32_t` and, having no users, cost nothing to
113 * narrow. Every code below is non-zero, so a caller testing `!= 0` — which is
114 * every caller today — is unaffected by ports becoming more specific.
115 *
116 * The values are written WITHOUT a cast on purpose. `((nros_platform_ret_t) 0)`
117 * is the more careful C, and it is why bindgen emitted none of these: it cannot
118 * evaluate a cast into a constant, so `nros-platform-cffi` carried a
119 * hand-written Rust copy of all three — a mirror of exactly the kind
120 * `check-ffi-struct-mirrors` exists to prevent, kept in step by nothing. Bare
121 * integer literals cross the generator, so there is now one definition. */
122
123typedef int8_t nros_platform_ret_t;
124
126#define NROS_PLATFORM_RET_OK 0
128#define NROS_PLATFORM_RET_ERROR -1
133#define NROS_PLATFORM_RET_UNSUPPORTED -5
138#define NROS_PLATFORM_RET_NOMEM -6
142#define NROS_PLATFORM_RET_INVALID -7
146#define NROS_PLATFORM_RET_TIMEOUT -8
147
148/* ---- Clock (monotonic) ---- */
149
165
179
180/* RFC-0073 / phase-352 W6 — `nros_platform_clock_ms` and
181 * `nros_platform_clock_us` are RETIRED. They were kept for one release as
182 * `static inline` wrappers behind NROS_PLATFORM_LEGACY_CLOCK_UNITS; both
183 * the wrappers and the escape hatch are now gone. Callers divide
184 * `nros_platform_clock_ns()` themselves — and a caller that hand-declares
185 * either retired name is caught by
186 * `scripts/check-retired-platform-clock-symbols.py` (issue #555). */
187
188/* ---- Clock (wall-clock epoch) ---- */
189
225
226/* ---- Allocation ---- */
227
230void *nros_platform_alloc(size_t size);
231
235void *nros_platform_realloc(void *ptr, size_t size);
236
238void nros_platform_dealloc(void *ptr);
239
240/* Canonical `malloc`/`free` C-ABI surface (issue-0038). nros-cpp's heap
241 * containers (`heap_string.hpp`, `heap_sequence.hpp`) allocate through
242 * `nros_platform_malloc` / `nros_platform_free` so C and C++ share one
243 * allocator. Defined ONCE here (replacing the former 5 per-header copies) as a
244 * thin forward to the platform `alloc`/`dealloc` funnel (RFC-0034 D6), GATED on
245 * the heap capability: a board without `NROS_PLATFORM_HAS_MALLOC` does not get
246 * the canonical malloc/free, so using a heap container on a heap-less board is a
247 * compile error (the 241.A gate), not a latent link failure. */
248#ifdef NROS_PLATFORM_HAS_MALLOC
249static inline void *nros_platform_malloc(size_t size) {
250 return nros_platform_alloc(size);
251}
252
253static inline void nros_platform_free(void *ptr) {
255}
256#endif /* NROS_PLATFORM_HAS_MALLOC */
257
263
293
296
297/* ---- Atomics ---- */
298/* RFC-0042 D1 / phase-243 — single portable atomic-bool pair (was per-RTOS
299 * `static inline` in the retired nros-c sub-headers: posix `__atomic`, zephyr
300 * `atomic_set`, freertos critical-section, bare-metal barrier). The `__atomic_*`
301 * builtins lower to a plain load/store + acquire/release fence for a
302 * naturally-aligned 1-byte `bool` on every target nros builds — no CAS /
303 * A-extension needed (riscv32imc never builds nros-c). Used directly (not C11
304 * `<stdatomic.h>`, which does not compile under g++). Header-only inline, so
305 * there is no extern symbol + no Rust-mirror entry. */
306static inline void nros_platform_atomic_store_bool(bool *ptr, bool value) {
307 __atomic_store_n(ptr, value, __ATOMIC_RELEASE);
308}
309
310static inline bool nros_platform_atomic_load_bool(const bool *ptr) {
311 return __atomic_load_n(ptr, __ATOMIC_ACQUIRE);
312}
313
314/* ---- Sleep ---- */
315
319
322
325
326/* ---- Cooperative yield ---- */
327
334
335/* ---- Random ---- */
336
348void nros_platform_random_fill(void *buf, size_t len);
349
350/* ---- Wall clock ---- */
351
375
376/* Issue 0532 item 5 — `nros_platform_time_now_ms`,
377 * `nros_platform_time_since_epoch_secs` and
378 * `nros_platform_time_since_epoch_nanos` are RETIRED, the same way
379 * phase-352 W6 retired `clock_ms` / `clock_us` rather than keeping
380 * wrappers. A caller that hand-declares any of the three is caught by
381 * `scripts/check-retired-platform-clock-symbols.py`. */
382
383/* ---- Threading: tasks ---- */
384
385/* ---- Task attributes ----
386 *
387 * phase-364 W3 (RFC-0076 D2). `attr` used to be an undefined `void *`: IGNORED
388 * by the posix and zephyr ports, a PRIVATE struct in the freertos and esp-idf
389 * ports, and MANDATORY on threadx (a `NULL` was a hard failure). Three struct
390 * types, no shared definition, and therefore no portable way to ask for a stack
391 * size — which is why phase-359 W7 wrote a bespoke C shim to spawn a NuttX tier
392 * with a 64 KiB stack, and why W10's generic spawn passes `NULL` and would fail
393 * on ThreadX.
394 *
395 * One type now, defined here, and `attr == NULL` means "every default" on
396 * EVERY port. */
397typedef struct {
400 const char *name;
440 int32_t priority;
442 int8_t core;
444 uint8_t flags;
446
448#define NROS_PLATFORM_TASK_DETACHED 0x01u
449
450/* ---- Normalised priority band (phase-364 W5) ----
451 *
452 * `0` = least urgent … `NROS_PLATFORM_PRIORITY_MAX` = most urgent. A port maps
453 * the band onto its native range; the map is documented at each port's
454 * `task_init` and is the ONLY place a direction is decided.
455 *
456 * The band is deliberately small. It is a portable ORDERING, not a claim that
457 * every RTOS has 256 usable levels — ThreadX ships 32 by default, FreeRTOS's
458 * `configMAX_PRIORITIES` is commonly 5 to 32, and a map that pretended
459 * otherwise would collapse distinct tiers onto one level without saying so. */
460#define NROS_PLATFORM_PRIORITY_MIN 0
461#define NROS_PLATFORM_PRIORITY_MAX 255
463#define NROS_PLATFORM_PRIORITY_INHERIT INT32_MIN
464
470#define NROS_PLATFORM_PRIORITY_RAW(n) (-0x40000000 - (int32_t) (n))
472#define NROS_PLATFORM_PRIORITY_IS_RAW(p) \
473 ((p) <= -0x40000000 && (p) != NROS_PLATFORM_PRIORITY_INHERIT)
475#define NROS_PLATFORM_PRIORITY_RAW_VALUE(p) (-0x40000000 - (int32_t) (p))
476
483
492int8_t nros_platform_task_init(void *task, void *attr,
493 void *(*entry)(void *), void *arg);
494
496int8_t nros_platform_task_join(void *task);
497
500int8_t nros_platform_task_detach(void *task);
501
504int8_t nros_platform_task_cancel(void *task);
505
508
511void nros_platform_task_free(void **task);
512
533
534/* ---- Opaque-storage sizes, at COMPILE time ----
535 *
536 * phase-364 W2 (RFC-0076 D1). The probes above answer a caller that allocates
537 * at runtime. They cannot answer one that embeds these objects BY VALUE —
538 * zenoh-pico's `_z_mutex_t` is a type, and a function call cannot size an
539 * array — so the same facts are also available as macros.
540 *
541 * These are UPPER BOUNDS over every supported port, not per-port exact sizes: a
542 * single header cannot know which port will link, and a consumer that embeds by
543 * value must reserve enough for the one that does. Each port asserts its own
544 * type fits (`_Static_assert` in its `platform.c`), so a bound that stops being
545 * true is a compile error in the port rather than a silent overrun in the
546 * consumer.
547 *
548 * They replace a hand-computed table in `zpico-sys` that recorded other
549 * platforms' sizes as `≈` values with a "2× safety margin", checked by nobody,
550 * about structs that are Kconfig-dependent on at least two of those platforms —
551 * issue 0570's shape. The numbers below are deliberately generous for the same
552 * reason the old ones were; the difference is that they are now checked.
553 *
554 * A port may raise a bound by defining it before including this header. */
555#ifndef NROS_PLATFORM_TASK_STORAGE_SIZE
556/* 512. ThreadX is the large one, and the number here is MEASURED, not
557 * estimated: `sizeof(TX_THREAD)` is **360** bytes on the 64-bit Linux port,
558 * plus this port's owned-stack pointer and padding.
559 *
560 * The estimate it replaces is worth keeping visible. `zpico-sys` recorded
561 * "ThreadX TX_THREAD ≈ 232" and sized its task storage at 256 — correct for a
562 * 32-bit port and 128 bytes short on a 64-bit one. That table was hand-written
563 * prose about another platform's struct, which is why phase-364 W2 replaced it
564 * with probes and `_Static_assert`s; this bound was raised BECAUSE one of those
565 * asserts failed on the first real ThreadX build, rather than because someone
566 * re-read the comment. */
567# define NROS_PLATFORM_TASK_STORAGE_SIZE 512
568#endif
569#ifndef NROS_PLATFORM_MUTEX_STORAGE_SIZE
570/* 256, not a tighter fit, and the reason is recorded rather than guessed:
571 * `zpico-sys` bounded this at 64 B, met ThreadX's `TX_MUTEX` (~120 B with
572 * ownership / inheritance / suspension-list fields), and silently corrupted the
573 * neighbouring field — presenting as a HANG in `Executor::open` after the zenoh
574 * handshake, because every mutex op on the in-band executor trampled a
575 * neighbour. Over-reserving costs bytes; under-reserving costs that. */
576# define NROS_PLATFORM_MUTEX_STORAGE_SIZE 256
577#endif
578#ifndef NROS_PLATFORM_MUTEX_REC_STORAGE_SIZE
579# define NROS_PLATFORM_MUTEX_REC_STORAGE_SIZE 256
580#endif
581#ifndef NROS_PLATFORM_CONDVAR_STORAGE_SIZE
582/* POSIX `pthread_cond_t` is 48 B; a composite RTOS condvar
583 * (`TX_MUTEX + TX_SEMAPHORE + UINT`) is ~184. Same reasoning as the mutex. */
584# define NROS_PLATFORM_CONDVAR_STORAGE_SIZE 256
585#endif
586#ifndef NROS_PLATFORM_STORAGE_ALIGN
587/* Every opaque type on every supported port is at most 8-byte aligned. */
588# define NROS_PLATFORM_STORAGE_ALIGN 8
589#endif
590
591
592/* ---- Threading: non-recursive mutex ---- */
593
599
600/* ---- Threading: recursive mutex ---- */
601
609
610/* ---- Threading: condition variables ---- */
611
616
645
648int8_t nros_platform_condvar_wait(void *cv, void *m);
649
661int8_t nros_platform_condvar_wait_until(void *cv, void *m, uint64_t abstime);
662
663/* ---- Threading: wake primitive (Phase 130) ----
664 *
665 * Binary-semaphore-shaped primitive used by the executor's wake_flag /
666 * spin_once cv-wait pair. Separate from `nros_platform_condvar_*` so
667 * the executor doesn't inherit zenoh-pico's pthread-shaped Zephyr
668 * ABI (which on libc hangs past `pthread_cond_timedwait` deadlines).
669 *
670 * Per-platform impl:
671 * * POSIX: `sem_t` with `sem_timedwait` (`CLOCK_MONOTONIC`).
672 * * Zephyr: `k_sem` (kernel-native, libc-pthread-free).
673 * * FreeRTOS: `xSemaphoreCreateBinary` + `xSemaphoreGiveFromISR`.
674 * * NuttX: POSIX `sem_t` via NuttX libc (`sem_timedwait`).
675 * * ThreadX: `tx_semaphore` (ISR-safe `tx_semaphore_put`).
676 * * bare: atomic flag + busy-spin against the platform clock.
677 *
678 * `wait_ms` returns 0 on signal, 1 on timeout, -1 on error.
679 * `signal_from_isr` returns -1 if the backend has no ISR-safe path;
680 * callers may fall back to `signal()` accepting the latency cost.
681 * Storage is opaque to the caller; size/alignment via the probe
682 * helpers below. */
685int8_t nros_platform_wake_wait_ms(void *w, uint32_t timeout_ms);
688
693
694/* ---- Critical section ---- */
695/* Phase 121.9 — global mutual exclusion against preemption + ISR
696 * delivery. Backs the Rust `critical_section::Impl` registration used
697 * by DDS, nros-rmw-{xrce,zenoh}, and any consumer of
698 * `critical_section::with()`. Reentrant by contract: every acquire
699 * must be paired with exactly one release, and the platform handles
700 * nesting (PRIMASK already stacks; pthread side uses a recursive
701 * mutex).
702 *
703 * The `uint32_t` token holds whatever the platform needs to restore
704 * the prior posture — Cortex-M PRIMASK bit, Cortex-R CPSR I-bit,
705 * RISC-V `mstatus.MIE` snapshot, pthread depth counter — and is
706 * opaque to the caller. */
709
710/* ---- Logging (Phase 88) ---- */
711/* Per-platform leveled log delivery, matching the post-Phase-129
712 * pattern: portable facade (`nros-log`) formats into a buffer and
713 * hands the rendered text to whichever `nros-platform-<rtos>` is
714 * linked in. POSIX writes to stderr; Zephyr routes through
715 * `LOG_MODULE_DECLARE(nros)` (or `printk` fallback); ESP-IDF goes
716 * through `esp_log_write`; NuttX through `syslog`; FreeRTOS /
717 * ThreadX / bare-metal expose a `register_log_writer(...)` helper
718 * in their platform crate so boards register the actual writer
719 * (UART / semihosting / defmt / RTT) once at startup.
720 *
721 * `severity`: matches `nros_log::Severity::as_u8()`:
722 * 0 = Trace, 1 = Debug, 2 = Info, 3 = Warn, 4 = Error, 5 = Fatal.
723 * Implementors should map onto the platform's nearest level.
724 *
725 * `name_ptr` / `name_len`: logger name (NOT null-terminated; UTF-8).
726 * May be empty (the catch-all logger).
727 * `msg_ptr` / `msg_len`: already-formatted message body (NOT null-
728 * terminated; UTF-8). Implementors that need a `CStr` must copy
729 * into their own buffer + append `'\0'`.
730 *
731 * No return value: log delivery never fails from the caller's POV.
732 * Platforms drop silently on internal overflow (e.g. RTT ring full).
733 *
734 * `nros_platform_log_flush`: best-effort drain of any internal
735 * buffer (RTT, syslog buffered chan, etc.). Default impl = no-op.
736 *
737 * Thread / ISR safety is documented per platform — see the table
738 * in `docs/roadmap/phase-88-nros-log.md`. The ABI itself is
739 * synchronous + reentrant-safe at the caller layer (a recursion
740 * guard in `nros-log` prevents fan-out re-entry). */
742 uint8_t severity,
743 const uint8_t *name_ptr, uintptr_t name_len,
744 const uint8_t *msg_ptr, uintptr_t msg_len);
746
747/* Board-supplied writer hook. ONLY meaningful on platforms whose
748 * `nros_platform_log_write` impl is itself a thin dispatcher to a
749 * board-registered fn (FreeRTOS, ThreadX, bare-metal). On platforms
750 * with a native logger (POSIX, Zephyr, ESP-IDF, NuttX), the symbol
751 * is absent and the board should not link against it.
752 *
753 * Board crates call this ONCE at startup, before any task / thread
754 * begins logging. Re-calling replaces the registration.
755 *
756 * `writer` matches the signature of `nros_platform_log_write`.
757 * `flusher` is optional (pass NULL for fully-synchronous writers). */
759 uint8_t severity,
760 const uint8_t *name_ptr, uintptr_t name_len,
761 const uint8_t *msg_ptr, uintptr_t msg_len);
762
763typedef void (*nros_platform_log_flush_fn_t)(void);
764
768
769/*
770 * Runtime locator override (nano-ros #166 / phase-286 W1).
771 *
772 * Returns a middleware locator to use INSTEAD of the build-time-baked default
773 * (`CONFIG_NROS_ZENOH_LOCATOR` / `option_env!("NROS_LOCATOR")`), or NULL to keep
774 * the bake. Only the native_sim/native_posix platform impl returns non-NULL
775 * (from `-testargs --nros-locator=<loc>`); every real-embedded impl returns
776 * NULL. Entry points (Rust `zephyr_component_main!`, the C/C++ entries) prefer
777 * this when non-NULL so native_sim tests can each dial a distinct per-test
778 * zenohd, retiring the shared-baked-port serialization.
779 *
780 * The returned pointer is owned by the platform (argv-backed) and valid for the
781 * process lifetime; the caller must not free it.
782 */
784
785/* ---- Fatal error (phase-366 / RFC-0077) ----
786 *
787 * The image's one ending. Rust's `#[panic_handler]`, a C precondition failure
788 * and a C++ terminate all arrive here, so an operator debugging a board has one
789 * place to look instead of four.
790 *
791 * Before this existed the ABI could express ALLOCATION but not fatality, so each
792 * language invented its own: `nros-c` spun silently, `nros-board-nuttx` printed
793 * and exited 1, the ThreadX RV64 board wrote UART and exited QEMU, the FreeRTOS
794 * board did semihosting + `bkpt` + spin. Four reasonable answers to four
795 * different questions, none of them the image's to choose.
796 *
797 * `msg` is a DIAGNOSTIC, not a C string: `len` bytes, no NUL required, possibly
798 * empty (`msg` may be NULL only when `len == 0`). It is not necessarily UTF-8 —
799 * a port that forwards to a text sink should treat it as bytes.
800 *
801 * Contract on the implementor:
802 * - MUST NOT return. Declared `_Noreturn` so a caller (and Rust's `-> !`) can
803 * rely on it.
804 * - MUST tolerate being called from ANY context — interrupt, scheduler
805 * locked, or before the kernel starts. That rules out anything needing a
806 * scheduler, which is why this is not simply "log at Fatal then halt".
807 * - SHOULD emit `msg` somewhere a human can read before terminating. A silent
808 * halt is the one behaviour no RTOS in this tree chose for itself.
809 *
810 * Spelled through `NROS_PLATFORM_NORETURN` because this header is included from
811 * C++ too (`nros-cpp`), where `_Noreturn` is not a keyword — that mismatch is a
812 * hard `'_Noreturn' does not name a type` in every C++ TU, which is how it was
813 * found.
814 *
815 * Ports map it to the fatal path they already have (`k_panic`, `PANIC()`,
816 * `esp_system_abort`, the FreeRTOS hook, `abort()`). A C/C++ image overrides the
817 * port's definition by defining this symbol strongly; a Rust image declares its
818 * own `#[panic_handler]` in the entry package. Either way the choice belongs to
819 * whoever builds the image — RFC-0077.
820 */
821#if defined(__cplusplus)
822# define NROS_PLATFORM_NORETURN [[noreturn]]
823#elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L
824# define NROS_PLATFORM_NORETURN _Noreturn
825#else
826# define NROS_PLATFORM_NORETURN __attribute__((noreturn))
827#endif
828
829NROS_PLATFORM_NORETURN void nros_platform_panic(const char *msg, size_t len);
830
831#ifdef __cplusplus
832} /* extern "C" */
833#endif
834
835#endif /* NROS_PLATFORM_H */
int8_t nros_platform_ret_t
Definition platform.h:123
size_t nros_platform_condvar_storage_size(void)
int8_t nros_platform_task_detach(void *task)
size_t nros_platform_mutex_rec_storage_size(void)
size_t nros_platform_condvar_storage_align(void)
static void * nros_platform_malloc(size_t size)
Definition platform.h:249
int8_t nros_platform_wake_init(void *w)
uint16_t nros_platform_random_u16(void)
void nros_platform_critical_section_release(uint32_t token)
void(* nros_platform_log_flush_fn_t)(void)
Definition platform.h:763
int8_t nros_platform_mutex_lock(void *m)
void nros_platform_log_flush(void)
int8_t nros_platform_mutex_rec_init(void *m)
uint64_t nros_platform_epoch_us(void)
int8_t nros_platform_wake_signal_from_isr(void *w)
int8_t nros_platform_condvar_wait_until(void *cv, void *m, uint64_t abstime)
int8_t nros_platform_task_join(void *task)
int8_t nros_platform_mutex_init(void *m)
void nros_platform_random_fill(void *buf, size_t len)
size_t nros_platform_task_storage_align(void)
int8_t nros_platform_task_init(void *task, void *attr, void *(*entry)(void *), void *arg)
const char * nros_runtime_locator_override(void)
uint8_t nros_platform_random_u8(void)
int8_t nros_platform_mutex_try_lock(void *m)
void nros_platform_sleep_s(size_t s)
int8_t nros_platform_mutex_rec_unlock(void *m)
size_t nros_platform_heap_used_bytes(void)
int8_t nros_platform_mutex_rec_try_lock(void *m)
void nros_platform_dealloc(void *ptr)
void nros_platform_sleep_ms(size_t ms)
uint64_t nros_platform_clock_ns(void)
int8_t nros_platform_wake_drop(void *w)
void nros_platform_task_attr_init(nros_platform_task_attr_t *attr)
#define NROS_PLATFORM_NORETURN
Definition platform.h:826
int8_t nros_platform_task_cancel(void *task)
size_t nros_platform_task_stack_unused_bytes(void)
int8_t nros_platform_mutex_drop(void *m)
size_t len
Definition platform.h:829
int8_t nros_platform_condvar_signal(void *cv)
static bool nros_platform_atomic_load_bool(const bool *ptr)
Definition platform.h:310
size_t nros_platform_wake_storage_align(void)
int8_t nros_platform_mutex_rec_lock(void *m)
void nros_platform_register_log_writer(nros_platform_log_writer_fn_t writer, nros_platform_log_flush_fn_t flusher)
int8_t nros_platform_condvar_wait(void *cv, void *m)
int8_t nros_platform_condvar_signal_from_isr(void *cv)
void nros_platform_log_write(uint8_t severity, const uint8_t *name_ptr, uintptr_t name_len, const uint8_t *msg_ptr, uintptr_t msg_len)
void nros_platform_yield_now(void)
size_t nros_platform_mutex_rec_storage_align(void)
static void nros_platform_atomic_store_bool(bool *ptr, bool value)
Definition platform.h:306
size_t nros_platform_mutex_storage_size(void)
void nros_platform_sleep_us(size_t us)
size_t nros_platform_task_storage_size(void)
int8_t nros_platform_mutex_rec_drop(void *m)
uint32_t nros_platform_critical_section_acquire(void)
int8_t nros_platform_wake_signal(void *w)
static void nros_platform_free(void *ptr)
Definition platform.h:253
void * nros_platform_realloc(void *ptr, size_t size)
int8_t nros_platform_mutex_unlock(void *m)
int8_t nros_platform_condvar_signal_all(void *cv)
size_t nros_platform_wake_storage_size(void)
uint64_t nros_platform_random_u64(void)
size_t nros_platform_heap_total_bytes(void)
void(* nros_platform_log_writer_fn_t)(uint8_t severity, const uint8_t *name_ptr, uintptr_t name_len, const uint8_t *msg_ptr, uintptr_t msg_len)
Definition platform.h:758
int8_t nros_platform_wake_wait_ms(void *w, uint32_t timeout_ms)
uint32_t nros_platform_random_u32(void)
uint64_t nros_platform_time_now_ns(void)
void nros_platform_task_free(void **task)
size_t nros_platform_mutex_storage_align(void)
uint64_t nros_platform_clock_resolution_ns(void)
int8_t nros_platform_condvar_drop(void *cv)
int8_t nros_platform_condvar_init(void *cv)
void * nros_platform_alloc(size_t size)
void nros_platform_task_exit(void)
Definition platform.h:397
const char * name
Definition platform.h:400
size_t stack_bytes
Definition platform.h:417
int32_t priority
Definition platform.h:440
void * stack_mem
Definition platform.h:423
uint8_t flags
Definition platform.h:444
int8_t core
Definition platform.h:442