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
nros/nros.h— convenience umbrella includenros/init.h—nros_support_init,nros_support_fininros/node.h—nros_node_init,nros_node_fininros/executor.h— spin loop, executor lifecyclenros/publisher.h/subscription.h— pub/subnros/service.h/client.h— servicesnros/action.h— actionsnros/parameter.h— parameter servicesnros/lifecycle.h— REP-2002 lifecycle states
Two-layer API. Every entity exposes two parallel C entry-point sets:
nros_*_init(Layer 1, caller polls) andnros_executor_register_*(Layer 2, executor callback). Layer 1 grew an_init_polling+try_recv_*_raw/send_*_rawfamily for inline-storage callers (no executor arena). Layer 2 keeps the existingnros_*_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-ownednros_wake_state_tPOD; the backend firescb(ctx)on rx / reply / request arrival. Per-channel for actions (set_{goal,cancel,get_result}_wake_callbackon the server,set_{goal_response,cancel_response,result,feedback}_wake_callbackon 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 withnros_action_client_set_goal_response_callback(),nros_action_client_set_feedback_callback(), andnros_action_client_set_result_callback(). The callbacks fire fromnros_executor_spin_some()— your spin loop is the only place callbacks run. - Blocking convenience:
nros_action_send_goal()andnros_action_get_result(). These call the async variant and then drivenros_executor_spin_some()internally on a wall-clock budget until the reply lands (or 15 s / 30 s timeout). They take thenros_executor_t*explicitly because the action client stores its handle as an opaque slot inside the executor (registered vianros_executor_register_action_client()). The same applies tonros_action_client_wait_for_action_server()andnros_action_client_action_server_is_ready(). Calling any of them from inside a dispatch callback returnsNROS_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.