Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

C API

The C user-facing surface lives in packages/core/nros-c/include/nros/*.h. Generated by Doxygen; always reflects the current main branch.

API reference

C API Doxygen — start here.

The umbrella header nros/nros.h pulls in every public surface a user application needs.

Where to start

Two-layer API. Every entity exposes two parallel C entry-point sets: nros_*_init (Layer 1, caller polls) and nros_executor_register_* (Layer 2, executor callback). Layer 1 grew an _init_polling + try_recv_*_raw / send_*_raw family for inline-storage callers (no executor arena). Layer 2 keeps the existing nros_*_init + executor-register pair. See Two-Layer API for the verb discipline and per-layer trade-offs.

Event-driven wake callbacks. Each L1 polling entity supports nros_*_set_wake_callback(entity, &state, cb, ctx) for event- driven RTOS / embassy callers. State is a caller-owned nros_wake_state_t POD; the backend fires cb(ctx) on rx / reply / request arrival. Per-channel for actions (set_{goal,cancel,get_result}_wake_callback on the server, set_{goal_response,cancel_response,result,feedback}_wake_callback on the client). See the Doxygen for signatures.

Async action client

<nros/action.h> exposes two parallel entry-point families for sending goals, requesting results, and cancelling:

  • Async (non-blocking): nros_action_send_goal_async(), nros_action_get_result_async(), nros_action_cancel_goal(), nros_action_try_recv_feedback(). Return immediately. Replies are delivered through the callbacks registered with nros_action_client_set_goal_response_callback(), nros_action_client_set_feedback_callback(), and nros_action_client_set_result_callback(). The callbacks fire from nros_executor_spin_some() — your spin loop is the only place callbacks run.
  • Blocking convenience: nros_action_send_goal() and nros_action_get_result(). These call the async variant and then drive nros_executor_spin_some() internally on a wall-clock budget until the reply lands (or 15 s / 30 s timeout). They take the nros_executor_t* explicitly because the action client stores its handle as an opaque slot inside the executor (registered via nros_executor_register_action_client()). The same applies to nros_action_client_wait_for_action_server() and nros_action_client_action_server_is_ready(). Calling any of them from inside a dispatch callback returns NROS_RET_REENTRANT.

The equivalent service client helper nros_client_call() does not take an explicit executor — the client stashes the executor pointer during nros_executor_register_client() and recovers it internally — but it follows the same async-then-spin contract.

Canonical pattern: declare the executor, register the client, then either call the blocking helper or drive nros_executor_spin_some() yourself between async calls until your callback flags the result. See the example layouts in examples/native/c/action-client/ and examples/qemu-arm-freertos/c/action-client/.

added a separate L1 polling family (nros_action_client_init_polling + the _raw send/recv siblings) that stores ActionClientCore inline in the nros_action_client_t._opaque slot and skips the executor entirely; see the Doxygen for the full L1 verb list.

CMake integration

Out-of-tree projects use the NanoRos::C CMake target and the nano_ros_generate_interfaces() function — covered in docs/reference/c-api-cmake.md.

Generating locally

doxygen packages/core/nros-c/Doxyfile
xdg-open target/doc/c-api/html/index.html

Internals (porting only)

The rmw-cffi and platform-cffi Doxygen sites are not part of the user API — they document the C vtables for porters writing a custom RMW backend or platform port. See RMW API and Platform API.