nros platform-cffi
Canonical C ABI for porting the nros platform abstraction
Loading...
Searching...
No Matches
Data Structures | Macros | Typedefs | Functions | Variables
platform.h File Reference

Canonical C ABI for the nros platform abstraction. More...

#include <stdint.h>
#include <stddef.h>
#include <stdbool.h>
Include dependency graph for platform.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  nros_platform_task_attr_t
 

Macros

#define NROS_PLATFORM_CONDVAR_STORAGE_SIZE   256
 
#define NROS_PLATFORM_HAS_ATOMICS
 
#define NROS_PLATFORM_HAS_MALLOC
 
#define NROS_PLATFORM_MUTEX_REC_STORAGE_SIZE   256
 
#define NROS_PLATFORM_MUTEX_STORAGE_SIZE   256
 
#define NROS_PLATFORM_NORETURN   __attribute__((noreturn))
 
#define NROS_PLATFORM_PRIORITY_INHERIT   INT32_MIN
 
#define NROS_PLATFORM_PRIORITY_IS_RAW(p)    ((p) <= -0x40000000 && (p) != NROS_PLATFORM_PRIORITY_INHERIT)
 
#define NROS_PLATFORM_PRIORITY_MAX   255
 
#define NROS_PLATFORM_PRIORITY_MIN   0
 
#define NROS_PLATFORM_PRIORITY_RAW(n)   (-0x40000000 - (int32_t) (n))
 
#define NROS_PLATFORM_PRIORITY_RAW_VALUE(p)   (-0x40000000 - (int32_t) (p))
 
#define NROS_PLATFORM_RET_ERROR   -1
 
#define NROS_PLATFORM_RET_INVALID   -7
 
#define NROS_PLATFORM_RET_NOMEM   -6
 
#define NROS_PLATFORM_RET_OK   0
 
#define NROS_PLATFORM_RET_TIMEOUT   -8
 
#define NROS_PLATFORM_RET_UNSUPPORTED   -5
 
#define NROS_PLATFORM_STORAGE_ALIGN   8
 
#define NROS_PLATFORM_TASK_DETACHED   0x01u
 
#define NROS_PLATFORM_TASK_STORAGE_SIZE   512
 

Typedefs

typedef void(* nros_platform_log_flush_fn_t) (void)
 
typedef 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)
 
typedef int8_t nros_platform_ret_t
 

Functions

 __attribute__ ((noreturn)) void nros_platform_panic(const char *msg
 
void * nros_platform_alloc (size_t size)
 
static bool nros_platform_atomic_load_bool (const bool *ptr)
 
static void nros_platform_atomic_store_bool (bool *ptr, bool value)
 
uint64_t nros_platform_clock_ns (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)
 
int8_t nros_platform_condvar_signal (void *cv)
 
int8_t nros_platform_condvar_signal_all (void *cv)
 
int8_t nros_platform_condvar_signal_from_isr (void *cv)
 
size_t nros_platform_condvar_storage_align (void)
 
size_t nros_platform_condvar_storage_size (void)
 
int8_t nros_platform_condvar_wait (void *cv, void *m)
 
int8_t nros_platform_condvar_wait_until (void *cv, void *m, uint64_t abstime)
 
uint32_t nros_platform_critical_section_acquire (void)
 
void nros_platform_critical_section_release (uint32_t token)
 
void nros_platform_dealloc (void *ptr)
 
uint64_t nros_platform_epoch_us (void)
 
static void nros_platform_free (void *ptr)
 
size_t nros_platform_heap_total_bytes (void)
 
size_t nros_platform_heap_used_bytes (void)
 
void nros_platform_log_flush (void)
 
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)
 
static void * nros_platform_malloc (size_t size)
 
int8_t nros_platform_mutex_drop (void *m)
 
int8_t nros_platform_mutex_init (void *m)
 
int8_t nros_platform_mutex_lock (void *m)
 
int8_t nros_platform_mutex_rec_drop (void *m)
 
int8_t nros_platform_mutex_rec_init (void *m)
 
int8_t nros_platform_mutex_rec_lock (void *m)
 
size_t nros_platform_mutex_rec_storage_align (void)
 
size_t nros_platform_mutex_rec_storage_size (void)
 
int8_t nros_platform_mutex_rec_try_lock (void *m)
 
int8_t nros_platform_mutex_rec_unlock (void *m)
 
size_t nros_platform_mutex_storage_align (void)
 
size_t nros_platform_mutex_storage_size (void)
 
int8_t nros_platform_mutex_try_lock (void *m)
 
int8_t nros_platform_mutex_unlock (void *m)
 
void nros_platform_random_fill (void *buf, size_t len)
 
uint16_t nros_platform_random_u16 (void)
 
uint32_t nros_platform_random_u32 (void)
 
uint64_t nros_platform_random_u64 (void)
 
uint8_t nros_platform_random_u8 (void)
 
void * nros_platform_realloc (void *ptr, size_t size)
 
void nros_platform_register_log_writer (nros_platform_log_writer_fn_t writer, nros_platform_log_flush_fn_t flusher)
 
void nros_platform_sleep_ms (size_t ms)
 
void nros_platform_sleep_s (size_t s)
 
void nros_platform_sleep_us (size_t us)
 
void nros_platform_task_attr_init (nros_platform_task_attr_t *attr)
 
int8_t nros_platform_task_cancel (void *task)
 
int8_t nros_platform_task_detach (void *task)
 
void nros_platform_task_exit (void)
 
void nros_platform_task_free (void **task)
 
int8_t nros_platform_task_init (void *task, void *attr, void *(*entry)(void *), void *arg)
 
int8_t nros_platform_task_join (void *task)
 
size_t nros_platform_task_stack_unused_bytes (void)
 
size_t nros_platform_task_storage_align (void)
 
size_t nros_platform_task_storage_size (void)
 
uint64_t nros_platform_time_now_ns (void)
 
int8_t nros_platform_wake_drop (void *w)
 
int8_t nros_platform_wake_init (void *w)
 
int8_t nros_platform_wake_signal (void *w)
 
int8_t nros_platform_wake_signal_from_isr (void *w)
 
size_t nros_platform_wake_storage_align (void)
 
size_t nros_platform_wake_storage_size (void)
 
int8_t nros_platform_wake_wait_ms (void *w, uint32_t timeout_ms)
 
void nros_platform_yield_now (void)
 
const char * nros_runtime_locator_override (void)
 

Variables

size_t len
 

Detailed Description

Canonical C ABI for the nros platform abstraction.

RFC-0042 D1 / phase-241 wave B — this is THE single canonical platform header, owned by nros-platform-api (the lowest crate, no deps). nros-c and nros-platform-cffi re-export it, so neither package's consumers need the other's include dir (it breaks the historical nros-c↔cffi header tangle, and there is exactly one file named <nros/platform.h> — no include-order race).

A platform implementor supplies the symbols declared here. Every nros binary links exactly one platform implementation; resolution is at link time — no runtime registration. Implementations may be any language with a C ABI; for Rust platform crates, nros-platform-cffi re-exports the Rust impl as #[unsafe(no_mangle)] extern "C" symbols matching the names below (its src/lib.rs extern block is the hand-written mirror, guarded byte-for-byte by c_stub_platform.rs).

Companion to the canonical-C-ABI RMW vtable (<nros/rmw_vtable.h>); the platform layer sits one tier below RMW.

Return-value conventions

Threading

All symbols must be safe to invoke from any thread. mutex_* / condvar_* must be safe under concurrent callers. mutex_rec_* must support same-thread re-entry (zenoh-pico re-enters the same mutex).

RTOS yields (yield_now) are not ISR-safe. Bare-metal yields built on core::hint::spin_loop() are.

Macro Definition Documentation

◆ NROS_PLATFORM_CONDVAR_STORAGE_SIZE

#define NROS_PLATFORM_CONDVAR_STORAGE_SIZE   256

◆ NROS_PLATFORM_HAS_ATOMICS

#define NROS_PLATFORM_HAS_ATOMICS

◆ NROS_PLATFORM_HAS_MALLOC

#define NROS_PLATFORM_HAS_MALLOC

◆ NROS_PLATFORM_MUTEX_REC_STORAGE_SIZE

#define NROS_PLATFORM_MUTEX_REC_STORAGE_SIZE   256

◆ NROS_PLATFORM_MUTEX_STORAGE_SIZE

#define NROS_PLATFORM_MUTEX_STORAGE_SIZE   256

◆ NROS_PLATFORM_NORETURN

#define NROS_PLATFORM_NORETURN   __attribute__((noreturn))

◆ NROS_PLATFORM_PRIORITY_INHERIT

#define NROS_PLATFORM_PRIORITY_INHERIT   INT32_MIN

Keep the creating task's priority.

◆ NROS_PLATFORM_PRIORITY_IS_RAW

#define NROS_PLATFORM_PRIORITY_IS_RAW (   p)     ((p) <= -0x40000000 && (p) != NROS_PLATFORM_PRIORITY_INHERIT)

True when p came from NROS_PLATFORM_PRIORITY_RAW.

◆ NROS_PLATFORM_PRIORITY_MAX

#define NROS_PLATFORM_PRIORITY_MAX   255

◆ NROS_PLATFORM_PRIORITY_MIN

#define NROS_PLATFORM_PRIORITY_MIN   0

◆ NROS_PLATFORM_PRIORITY_RAW

#define NROS_PLATFORM_PRIORITY_RAW (   n)    (-0x40000000 - (int32_t) (n))

Escape hatch: pass n to the kernel untouched, bypassing the band.

Encoded as a large negative so it cannot collide with a band value, and so a port that has not implemented the escape sees an out-of-band number rather than a plausible-looking priority.

◆ NROS_PLATFORM_PRIORITY_RAW_VALUE

#define NROS_PLATFORM_PRIORITY_RAW_VALUE (   p)    (-0x40000000 - (int32_t) (p))

The raw value p carries. Only valid when IS_RAW(p).

◆ NROS_PLATFORM_RET_ERROR

#define NROS_PLATFORM_RET_ERROR   -1

Generic failure not covered by a more specific code.

◆ NROS_PLATFORM_RET_INVALID

#define NROS_PLATFORM_RET_INVALID   -7

The caller passed something impossible — a NULL where storage is required, a zero-sized stack, an out-of-range priority. Retrying unchanged cannot help; this is a bug in the caller, not a condition of the platform.

◆ NROS_PLATFORM_RET_NOMEM

#define NROS_PLATFORM_RET_NOMEM   -6

A resource was exhausted NOW — kernel heap, task slot, handle table. The operation is supported and may succeed later. NOT cacheable: a caller that treats this as permanent turns a momentary shortage into a dead feature (issue 0246).

◆ NROS_PLATFORM_RET_OK

#define NROS_PLATFORM_RET_OK   0

Operation completed successfully.

◆ NROS_PLATFORM_RET_TIMEOUT

#define NROS_PLATFORM_RET_TIMEOUT   -8

A bounded wait reached its deadline without the event. Not a failure of the call — nros_platform_wake_wait_ms already returns 1 for this and keeps doing so; this code is for the operations that have no such convention.

◆ NROS_PLATFORM_RET_UNSUPPORTED

#define NROS_PLATFORM_RET_UNSUPPORTED   -5

The platform does not implement this operation — and never will, in this build. A single-threaded bare-metal port has no tasks; a port without an ISR-safe signal has none. Cacheable: asking again cannot change the answer, so a caller may record it once and stop trying.

◆ NROS_PLATFORM_STORAGE_ALIGN

#define NROS_PLATFORM_STORAGE_ALIGN   8

◆ NROS_PLATFORM_TASK_DETACHED

#define NROS_PLATFORM_TASK_DETACHED   0x01u

The task is never joined; its resources are reclaimed when it exits.

◆ NROS_PLATFORM_TASK_STORAGE_SIZE

#define NROS_PLATFORM_TASK_STORAGE_SIZE   512

Typedef Documentation

◆ nros_platform_log_flush_fn_t

typedef void(* nros_platform_log_flush_fn_t) (void)

◆ nros_platform_log_writer_fn_t

typedef 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)

◆ nros_platform_ret_t

typedef int8_t nros_platform_ret_t

Function Documentation

◆ __attribute__()

__attribute__ ( (noreturn)  ) const

◆ nros_platform_alloc()

void * nros_platform_alloc ( size_t  size)

Allocate size bytes; return NULL on failure. May be called from any thread.

◆ nros_platform_atomic_load_bool()

static bool nros_platform_atomic_load_bool ( const bool *  ptr)
inlinestatic

◆ nros_platform_atomic_store_bool()

static void nros_platform_atomic_store_bool ( bool *  ptr,
bool  value 
)
inlinestatic

◆ nros_platform_clock_ns()

uint64_t nros_platform_clock_ns ( void  )

Monotonic nanoseconds since a platform-defined epoch (boot, program start, …). Never decreases. Wraps after ~584 years.

Must be backed by a hardware counter or the OS tick — never by a software counter that only advances when polled.

Available immediately after platform init, before any other nros subsystem. SHOULD be callable from an ISR; a port whose clock is not ISR-safe must say so in its port documentation.

RFC-0073: this replaced the former clock_ms / clock_us pair. Ports that can convert without a runtime division should — where the counter frequency divides 1e9 (25/50/100/125/200/250 MHz) a compile-time ns-per-cycle multiply is ~2.5x cheaper than the divide it replaces.

◆ nros_platform_clock_resolution_ns()

uint64_t nros_platform_clock_resolution_ns ( void  )

Granularity of nros_platform_clock_ns, in nanoseconds: the smallest non-zero difference two successive reads can report.

Examples: 1000000 for a 1 kHz tick, 40 for a 25 MHz cycle counter, 1000 for a microsecond hardware timer.

Must be non-zero, and constant for the lifetime of the program after platform init. A port whose underlying rate is only known at runtime returns the resolved value; one whose rate can change under it returns the COARSEST value it may exhibit. There is no "unknown" encoding — a port that cannot answer honestly is reporting a clock it cannot honestly offer.

◆ nros_platform_condvar_drop()

int8_t nros_platform_condvar_drop ( void *  cv)

◆ nros_platform_condvar_init()

int8_t nros_platform_condvar_init ( void *  cv)

◆ nros_platform_condvar_signal()

int8_t nros_platform_condvar_signal ( void *  cv)

◆ nros_platform_condvar_signal_all()

int8_t nros_platform_condvar_signal_all ( void *  cv)

◆ nros_platform_condvar_signal_from_isr()

int8_t nros_platform_condvar_signal_from_isr ( void *  cv)

Phase 124.B.7.a — ISR-safe signal.

Callable from interrupt context. nros_platform_condvar_signal is NOT ISR-safe on every platform (POSIX pthread_cond_signal isn't on the async-signal-safe function list; RTOS condvar primitives often require thread context). Backends MUST use this variant when triggering from an ISR or POSIX signal handler.

Per-platform implementation:

  • POSIX: pipe write — async-signal-safe; a runtime worker thread forwards to the underlying condvar. (Linux may use eventfd instead, which is NOT POSIX — signalfd/eventfd are Linux syscalls, which is why nros-node's worker is target_os = "linux"-gated.)
  • Zephyr: k_sem_give on the wake semaphore (ISR-safe).
  • FreeRTOS: xSemaphoreGiveFromISR + portYIELD_FROM_ISR on the wake semaphore.
  • NuttX: sem_post (POSIX-safe under NuttX) on the wake sem.
  • ThreadX: tx_event_flags_set on the wake event flag group (ISR-safe).
  • Bare-metal: atomic flag store + __SEV() (Cortex-M).

Returns non-zero on error (e.g. ISR-unsafe call on a backend that mandates ISR-context-only via a separate primitive). Backends without an ISR-safe path return non-zero so callers can fall back to thread-context signal (with the obvious latency cost).

◆ nros_platform_condvar_storage_align()

size_t nros_platform_condvar_storage_align ( void  )

◆ nros_platform_condvar_storage_size()

size_t nros_platform_condvar_storage_size ( void  )

◆ nros_platform_condvar_wait()

int8_t nros_platform_condvar_wait ( void *  cv,
void *  m 
)

Atomically release m and block on cv. The mutex is re-acquired before this function returns.

◆ nros_platform_condvar_wait_until()

int8_t nros_platform_condvar_wait_until ( void *  cv,
void *  m,
uint64_t  abstime 
)

Like condvar_wait, but with an absolute monotonic deadline in MILLISECONDS on the nros_platform_clock_ns() epoch — i.e. clock_ns() / 1000000. Returns non-zero on timeout.

Spelt out because this said "`clock_ms` units" after RFC-0073 / phase-352 W6 retired nros_platform_clock_ms: it named a function that no longer exists, leaving a port author no way to resolve the unit from this header. The unit itself never changed — every port names the parameter abstime_ms and the Rust trait says milliseconds — so this is the wording catching up, not an ABI change.

◆ nros_platform_critical_section_acquire()

uint32_t nros_platform_critical_section_acquire ( void  )

◆ nros_platform_critical_section_release()

void nros_platform_critical_section_release ( uint32_t  token)

◆ nros_platform_dealloc()

void nros_platform_dealloc ( void *  ptr)

Free a previously allocated block. NULL is a no-op.

◆ nros_platform_epoch_us()

uint64_t nros_platform_epoch_us ( void  )

Microseconds since the UNIX EPOCH (1970-01-01T00:00:00Z), or 0 when this platform has no wall-clock source.

READ THIS BEFORE REACHING FOR nros_platform_clock_ns (issue 0758). The two clocks in this header differ by one word in their names and by the only property that matters for interop:

  • nros_platform_clock_ns is MONOTONIC and boot-relative. Use it for durations, deadlines, spin gaps, timeouts — anything comparing two readings from THIS image. It is meaningless to a peer.
  • nros_platform_epoch_us is ABSOLUTE. Use it for message stamps and anything a peer will compare against its own clock.

Reaching for the wrong one does not fail to build and does not fail locally; it fails at a peer, which is the expensive place to find out. The concrete case is the consumer this exists for: an embedded island stamped control commands from its boot epoch and Autoware's vehicle_cmd_gate rejected every one as stale, so autonomous mode could never actuate.

0 MEANS "NO WALL CLOCK", not "the epoch". Per this header's clock rule (see the top of file: "If the platform has no clock, return `0`") this never errors. A caller that gets 0 knows the image cannot stamp absolute time and should keep publishing boot-relative stamps knowingly, rather than publishing a confidently wrong absolute one. 1970 is not a plausible reading, so the sentinel costs no real value.

Not required to be monotonic: a platform that acquires its epoch after boot (SNTP, RTC handoff) will JUMP when it does, and may jump backwards. Callers needing monotonicity use nros_platform_clock_ns.

Need not be ISR-safe, and unlike nros_platform_clock_ns need not be available immediately after platform init — a port that acquires its epoch over the network necessarily answers 0 until it has.

◆ nros_platform_free()

static void nros_platform_free ( void *  ptr)
inlinestatic

◆ nros_platform_heap_total_bytes()

size_t nros_platform_heap_total_bytes ( void  )

Total managed heap size in bytes (used + free), or 0 if unknown.

◆ nros_platform_heap_used_bytes()

size_t nros_platform_heap_used_bytes ( void  )

Bytes currently allocated from the platform heap, or 0 if the port does not instrument it. Phase 230 / RFC-0034 D7: the true unified figure where the platform owns one kernel heap shared by the C side and the Rust #[global_allocator].

◆ nros_platform_log_flush()

void nros_platform_log_flush ( void  )

◆ nros_platform_log_write()

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 
)

◆ nros_platform_malloc()

static void * nros_platform_malloc ( size_t  size)
inlinestatic

◆ nros_platform_mutex_drop()

int8_t nros_platform_mutex_drop ( void *  m)

◆ nros_platform_mutex_init()

int8_t nros_platform_mutex_init ( void *  m)

◆ nros_platform_mutex_lock()

int8_t nros_platform_mutex_lock ( void *  m)

◆ nros_platform_mutex_rec_drop()

int8_t nros_platform_mutex_rec_drop ( void *  m)

◆ nros_platform_mutex_rec_init()

int8_t nros_platform_mutex_rec_init ( void *  m)

Initialise a recursive mutex (same-thread re-entry permitted). Required by zenoh-pico.

◆ nros_platform_mutex_rec_lock()

int8_t nros_platform_mutex_rec_lock ( void *  m)

◆ nros_platform_mutex_rec_storage_align()

size_t nros_platform_mutex_rec_storage_align ( void  )

◆ nros_platform_mutex_rec_storage_size()

size_t nros_platform_mutex_rec_storage_size ( void  )

◆ nros_platform_mutex_rec_try_lock()

int8_t nros_platform_mutex_rec_try_lock ( void *  m)

◆ nros_platform_mutex_rec_unlock()

int8_t nros_platform_mutex_rec_unlock ( void *  m)

◆ nros_platform_mutex_storage_align()

size_t nros_platform_mutex_storage_align ( void  )

◆ nros_platform_mutex_storage_size()

size_t nros_platform_mutex_storage_size ( void  )

Opaque-storage sizing for the lock family, matching wake and task. Pure functions, callable before the corresponding _init.

◆ nros_platform_mutex_try_lock()

int8_t nros_platform_mutex_try_lock ( void *  m)

◆ nros_platform_mutex_unlock()

int8_t nros_platform_mutex_unlock ( void *  m)

◆ nros_platform_random_fill()

void nros_platform_random_fill ( void *  buf,
size_t  len 
)

Fill len bytes at buf with random data.

◆ nros_platform_random_u16()

uint16_t nros_platform_random_u16 ( void  )

Random u16. See random_u8 notes.

◆ nros_platform_random_u32()

uint32_t nros_platform_random_u32 ( void  )

Random u32. See random_u8 notes.

◆ nros_platform_random_u64()

uint64_t nros_platform_random_u64 ( void  )

Random u64. See random_u8 notes.

◆ nros_platform_random_u8()

uint8_t nros_platform_random_u8 ( void  )

Random u8. Cryptographically random where the platform has an entropy source; otherwise a seeded PRNG. Must be deterministic within a single test session for reproducibility.

◆ nros_platform_realloc()

void * nros_platform_realloc ( void *  ptr,
size_t  size 
)

Resize the block at ptr to size bytes. Equivalent to libc realloc: NULL ptr → fresh alloc; 0 size → free + return NULL. Preserves contents up to min(old, new).

◆ nros_platform_register_log_writer()

void nros_platform_register_log_writer ( nros_platform_log_writer_fn_t  writer,
nros_platform_log_flush_fn_t  flusher 
)

◆ nros_platform_sleep_ms()

void nros_platform_sleep_ms ( size_t  ms)

Sleep at least ms milliseconds.

◆ nros_platform_sleep_s()

void nros_platform_sleep_s ( size_t  s)

Sleep at least s seconds.

◆ nros_platform_sleep_us()

void nros_platform_sleep_us ( size_t  us)

Sleep at least us microseconds. Spin if the platform clock has no sub-millisecond timer.

◆ nros_platform_task_attr_init()

void nros_platform_task_attr_init ( nros_platform_task_attr_t attr)

Fill attr with the defaults — equivalent to passing NULL to task_init.

Callers use this rather than a designated initialiser so that a field added to the struct later stays source-compatible for out-of-tree ports.

◆ nros_platform_task_cancel()

int8_t nros_platform_task_cancel ( void *  task)

Request task to terminate at the next cancellation point. Cooperative: a task that never reaches a cancel point will not stop.

◆ nros_platform_task_detach()

int8_t nros_platform_task_detach ( void *  task)

Mark task as detached — its storage is reclaimed on exit without a join.

◆ nros_platform_task_exit()

void nros_platform_task_exit ( void  )

Terminate the calling task immediately. Does not return.

◆ nros_platform_task_free()

void nros_platform_task_free ( void **  task)

Free task storage allocated by task_init. Called after task_join or task_detach + exit.

◆ nros_platform_task_init()

int8_t nros_platform_task_init ( void *  task,
void *  attr,
void *(*)(void *)  entry,
void *  arg 
)

Spawn a new task. task is opaque caller-provided storage (size from nros_platform_task_storage_size); attr is a nros_platform_task_attr_t *, or NULL for every default; entry is the task entry point; arg is forwarded to entry.

Returns NROS_PLATFORM_RET_OK, or INVALID (a NULL where storage or an entry is required), NOMEM (resources exhausted now — retry may succeed) or UNSUPPORTED (this port has no tasks at all).

◆ nros_platform_task_join()

int8_t nros_platform_task_join ( void *  task)

Block until task exits. Cleans up task storage on success.

◆ nros_platform_task_stack_unused_bytes()

size_t nros_platform_task_stack_unused_bytes ( void  )

Smallest number of bytes ever left unused on the CALLING task's stack, or 0 if this port cannot report it.

HEADROOM, not usage, because that is what both kernels natively track and it is the number a safety argument needs: how close the worst observed excursion came to the end of the stack.

The heap has had nros_platform_heap_used_bytes since RFC-0034 D7; the stack had nothing, and stack overflow is the classic way one component corrupts another's state. ISO 26262 treats spatial freedom from interference as a first-class requirement and AUTOSAR pairs memory protection with stack monitoring for exactly this reason. Without a portable probe the only recourse is a per-RTOS one: this repo's Zephyr lane greps thread_analyzer printk output in CI, which is a text scrape of a debug facility standing in for a platform capability, and reports nothing on any other port.

SELF only, deliberately. Both kernels answer for the calling task with no handle (uxTaskGetStackHighWaterMark(NULL), k_thread_stack_space_get with k_current_get()), whereas answering for an arbitrary task needs a native handle this ABI does not carry – on Zephyr the task storage is a pthread_t and the mapping to k_thread * is not public. A task reporting its own headroom is also the shape the callers want: each tier says how much of its own stack it has ever needed.

0 means "this port does not instrument it", matching nros_platform_heap_used_bytes. It is not a claim that the stack is full.

◆ nros_platform_task_storage_align()

size_t nros_platform_task_storage_align ( void  )

◆ nros_platform_task_storage_size()

size_t nros_platform_task_storage_size ( void  )

Opaque-storage sizing for task, mirroring the wake primitive's probes below. Both are pure functions (no global state) and may be called before nros_platform_task_init.

phase-359 W10 — added because task_init's "size determined by the implementor" had no way to ASK. A C caller can write pthread_t t; and pass &t; a Rust caller cannot, and hard-coding a size is precisely issue 0570 (Rust's 20-byte pthread_attr_t met NuttX's 56-byte one and smashed the caller's frame). The wake primitive already solved this the right way; tasks now match it.

◆ nros_platform_time_now_ns()

uint64_t nros_platform_time_now_ns ( void  )

Wall-clock nanoseconds since the Unix epoch, or 0 if the platform has no real-time clock.

ONE symbol for one fact, mirroring what RFC-0073 / phase-352 did for the monotonic clock. It replaced time_now_ms + time_since_epoch_secs + time_since_epoch_nanos (issue 0532 item 5).

Why the split had to go, beyond tidiness: the ABI spent ONE INSTANT over two symbols, and each call sampled the clock separately (the POSIX port issued its own clock_gettime in each). A second boundary landing between the two reads paired the OLD second with the NEW sub-second remainder — a timestamp that jumped a full second BACKWARDS, rarely and silently. Both nros-core and nros-node carried a bounded re-read loop to paper over it; a single read cannot tear, so those loops are gone.

u64 ns spans ~584 years from 1970, so it also retires the uint32_t seconds field, which overflowed in 2106.

Ports convert from whatever they have — a port with only seconds returns secs * 1000000000ULL, and one with no RTC returns 0. Callers wanting milliseconds divide by 1000000; wanting a (secs, nanos) pair, divide and remainder by 1000000000.

◆ nros_platform_wake_drop()

int8_t nros_platform_wake_drop ( void *  w)

◆ nros_platform_wake_init()

int8_t nros_platform_wake_init ( void *  w)

◆ nros_platform_wake_signal()

int8_t nros_platform_wake_signal ( void *  w)

◆ nros_platform_wake_signal_from_isr()

int8_t nros_platform_wake_signal_from_isr ( void *  w)

◆ nros_platform_wake_storage_align()

size_t nros_platform_wake_storage_align ( void  )

◆ nros_platform_wake_storage_size()

size_t nros_platform_wake_storage_size ( void  )

Opaque-storage sizing. Both helpers are pure functions (no global state) and may be called before nros_platform_wake_init.

◆ nros_platform_wake_wait_ms()

int8_t nros_platform_wake_wait_ms ( void *  w,
uint32_t  timeout_ms 
)

◆ nros_platform_yield_now()

void nros_platform_yield_now ( void  )

Voluntarily yield the current task / thread. On bare-metal, core::hint::spin_loop() is acceptable; on RTOSes use the native cooperative-yield primitive (k_yield, vPortYield, tx_thread_relinquish, sched_yield, …). RTOS yields are not ISR-safe.

◆ nros_runtime_locator_override()

const char * nros_runtime_locator_override ( void  )

Variable Documentation

◆ len

size_t len