|
nros platform-cffi
Canonical C ABI for porting the nros platform abstraction
|
#include <platform.h>
Data Fields | |
| int8_t | core |
| uint8_t | flags |
| const char * | name |
| int32_t | priority |
| size_t | stack_bytes |
| void * | stack_mem |
| int8_t nros_platform_task_attr_t::core |
SMP core to pin to, or -1 for unpinned. Ignored on single-core.
| uint8_t nros_platform_task_attr_t::flags |
NROS_PLATFORM_TASK_* flags below.
| const char* nros_platform_task_attr_t::name |
Task name for the kernel's own tables and crash dumps. NULL = the port's default. Ports whose kernel has no name concept ignore it.
| int32_t nros_platform_task_attr_t::priority |
Scheduling priority in the NORMALISED band: 0 = least urgent, larger = more urgent, NROS_PLATFORM_PRIORITY_INHERIT = keep the creating task's.
phase-364 W5. This was "platform-native", and the natives disagree: 0 is the HIGHEST priority on ThreadX and the LOWEST on FreeRTOS, while Zephyr runs lower-is-more-urgent with negatives reserved for cooperative threads. A tier priority is authored ONCE, in system.toml, and deployed to several of them — so the same number meant "run me first" on one board and "run me last" on another, with nothing in the ABI recording which convention a port used.
Each port maps this band onto its own range and documents the map at its task_init. Use NROS_PLATFORM_PRIORITY_RAW(n) to bypass the band when tuning one RTOS against its own documentation — that is a legitimate thing to do, and the band should not make it impossible.
| size_t nros_platform_task_attr_t::stack_bytes |
Minimum stack size in BYTES. 0 = the port's default.
A FLOOR, not an exact size (issue 0612). Every port has a minimum of its own — PTHREAD_STACK_MIN, configMINIMAL_STACK_SIZE, TX_MINIMUM_STACK — and those differ by an order of magnitude, and on POSIX differ by ARCHITECTURE (16384 on glibc/x86_64, 131072 on glibc/aarch64). So no portable caller can name a number that is legal everywhere, and a port that treats a small request as an error turns a reasonable ask into a dead capability: that is exactly how Executor::signal_fd() returned NotInitialized on every Linux host. A port raises this to its own minimum; it never lowers it, and never refuses for being too small.
Always bytes, never words: FreeRTOS's xTaskCreate takes words, and the private struct it replaced called the field stack_depth while ThreadX's identically-named field was bytes. The conversion belongs in the one port that needs it, not in every caller.
| void* nros_platform_task_attr_t::stack_mem |
Caller-provided stack memory, or NULL to let the port obtain it.
ThreadX requires the stack from its caller; POSIX, FreeRTOS and ESP-IDF let the kernel allocate and ignore this. A port that needs memory and is given NULL obtains it itself and releases it in task_free.