ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
Loading...
Searching...
No Matches
ra8_c6link.c File Reference

Link lifecycle, frame routing and the identity round-trip. More...

#include "ra8_c6link.h"
#include <stddef.h>
#include <stdint.h>
#include "ra8_attributes.h"
#include "ra8_c6link_internal.h"
Include dependency graph for ra8_c6link.c:

Go to the source code of this file.

Functions

uint8_t priv_c6link_copy_str (char *dst, uint8_t cap, const ProtobufCBinaryData *src)
 Copy a length-counted binary field into a NUL-terminated string.
bool priv_c6link_copy_mac (ra8_c6link_mac_t *dst, const ProtobufCBinaryData *src)
 Copy a binary field into a MAC address, all-or-nothing.
void priv_c6link_emit (ra8_c6link_t *link, const ra8_c6link_event_t *ev)
 Deliver one decoded announcement to the registered callback.
bool priv_c6link_dispatch (ra8_c6link_t *link, const ra8_c6link_rx_view_t *view)
 Route one well-formed received frame to whatever understands it.
static ra8_err_t internal_c6link_check_cfg (const ra8_c6link_cfg_t *cfg)
 Reject a configuration the link cannot honour.
ra8_err_t ra8_c6link_open (ra8_c6link_t *link, const ra8_c6link_cfg_t *cfg)
 Bind a transport to a link handle and make it usable.
ra8_err_t ra8_c6link_close (ra8_c6link_t *link)
 Release a link handle.
bool ra8_c6link_is_open (const ra8_c6link_t *link)
 Report whether a handle is currently open.
ra8_err_t ra8_c6link_last_fault (const ra8_c6link_t *link, ra8_c6link_fault_t *out)
 Report the last request that failed on this link.
ra8_err_t ra8_c6link_poll (ra8_c6link_t *link, uint16_t max_transactions, ra8_c6link_stats_t *stats)
 Clock transactions, delivering whatever the co-processor sends.
ra8_err_t ra8_c6link_await_ready (ra8_c6link_t *link, uint16_t max_transactions, ra8_c6link_fw_version_t *out)
 Announce this host and prove the co-processor is answering.
static ra8_err_t internal_c6link_take_fw (void *ctx, const void *msg_v)
 Extract the co-processor identity from its answer.
ra8_err_t ra8_c6link_fw_version (ra8_c6link_t *link, ra8_c6link_fw_version_t *out)
 Ask the co-processor to identify itself.
ra8_err_t ra8_c6link_eth_send (ra8_c6link_t *link, const uint8_t *frame, uint16_t len)
 Hand one 802.3 frame to the co-processor for transmission.

Detailed Description

Link lifecycle, frame routing and the identity round-trip.

Tag
[Ring 4 / PAL] {World: NS}

The handle's own file: opening and closing it, deciding which consumer a received frame belongs to, delivering announcements, and the one request that belongs to the link rather than to Wi-Fi – asking the co-processor who it is.

Why the identity request lives here
Req_GetCoprocessorFwVersion is the cheapest complete proof that the whole stack works, because its answer is a fact this host can check rather than merely receive: this firmware is built against a pinned esp-hosted commit and the co-processor image was built from the same one, so the two versions must agree exactly. A bring-up that gets the right version back has proven framing, checksum, envelope, protobuf encode, protobuf decode and UID correlation in one call.
Since
0.1.0

Definition in file ra8_c6link.c.

Function Documentation

◆ internal_c6link_check_cfg()

ra8_err_t internal_c6link_check_cfg ( const ra8_c6link_cfg_t * cfg)
static

Reject a configuration the link cannot honour.

Rejects a seam with a missing row here rather than discovering it as a null call at the first transaction, and refuses an arena too small to decode the largest message this library reads.

Parameters
[in]cfgConfiguration the caller supplied; must be non-null.
Returns
ra8_err_t Error code.
Return values
k_ra8_okEvery field is usable.
k_ra8_err_null_ptrA transport row or the arena pointer was null.
k_ra8_err_invalid_sizeThe arena is smaller than the minimum.
Precondition
cfg is non-null, which the caller has already checked.
The caller has not yet copied anything out of cfg.
Postcondition
No state is modified.
Exactly one code is returned, naming the first failing check.
Note
Split out of ra8_c6link_open so that function stays inside the NASA Rule 4 length budget.
Since
0.1.0

Definition at line 134 of file ra8_c6link.c.

References ra8_c6link_cfg::arena, ra8_c6link_cfg::arena_bytes, ra8_c6link_transport::delay_ms, ra8_c6link_transport::handshake_active, k_ra8_c6link_arena_min, k_ra8_err_invalid_size, k_ra8_err_null_ptr, k_ra8_ok, RA8_INTERNAL, ra8_c6link_transport::transfer, and ra8_c6link_cfg::transport.

Referenced by ra8_c6link_open().

◆ internal_c6link_take_fw()

ra8_err_t internal_c6link_take_fw ( void * ctx,
const void * msg_v )
static

Extract the co-processor identity from its answer.

The co-processor's identity is the host/co-processor version lock, so every field is copied out for the caller to compare rather than judged here.

Parameters
[in]ctxA ra8_c6link_take_ctx_t whose out is the identity record.
[in]msg_vThe decoded Rpc; must be non-null.
Returns
ra8_err_t Error code.
Return values
k_ra8_okThe identity was copied out.
k_ra8_err_protocol_errorThe answer carried no body, or the co-processor reported a failure.
Precondition
ctx names a live link and a writable identity record.
msg_v is still owned by the decoder.
Postcondition
On success every field of the record is set.
On failure the link's fault slot names the request.
Note
Runs inside the pump, on the polling thread.
Since
0.1.0

Definition at line 291 of file ra8_c6link.c.

References ra8_c6link_fw_version::chip_id, k_ra8_err_protocol_error, ra8_c6link_take_ctx::link, ra8_c6link_fw_version::major, ra8_c6link_fw_version::minor, ra8_c6link_take_ctx::out, ra8_c6link_fw_version::patch, priv_c6link_copy_str(), priv_c6link_resp(), RA8_INTERNAL, ra8_c6link_fw_version::target, and ra8_c6link_fw_version::target_len.

Referenced by ra8_c6link_fw_version().

◆ priv_c6link_copy_mac()

bool priv_c6link_copy_mac ( ra8_c6link_mac_t * dst,
const ProtobufCBinaryData * src )
nodiscard

Copy a binary field into a MAC address, all-or-nothing.

Parameters
[out]dstAddress to fill; must be non-null.
[in]srcBinary field from a decoded message; null clears dst.
Returns
true when the field held exactly k_ra8_c6link_mac_bytes octets.
Return values
truedst holds the address.
falseThe field was absent or the wrong length; dst is cleared.
Precondition
dst does not overlap src.
The caller treats a false return as a protocol failure, not a default.
Postcondition
dst is either fully written or fully cleared.
src is not modified.
Note
Pure copying; safe from any context.
Example:
(void)priv_c6link_copy_mac(&ev.bssid, &body->bssid);
See also
priv_c6link_copy_str
Since
0.1.0

Definition at line 56 of file ra8_c6link.c.

References k_ra8_c6link_mac_bytes, ra8_c6link_mac::octet, and RA8_PRIV.

Referenced by internal_c6link_rpc_ev_connected(), internal_c6link_rpc_ev_disconnected(), internal_c6link_take_ap(), and internal_c6link_take_mac().

◆ priv_c6link_copy_str()

uint8_t priv_c6link_copy_str ( char * dst,
uint8_t cap,
const ProtobufCBinaryData * src )

Copy a length-counted binary field into a NUL-terminated string.

Shared by the event decoder and the AP-record decoder. The co-processor supplies the bytes, so nothing about them is trusted: the copy is bounded by the destination and terminated whatever the source did.

Parameters
[out]dstDestination; must be non-null and cap bytes long.
[in]capBytes available at dst, including the terminator.
[in]srcBinary field from a decoded message; null copies nothing.
Returns
The number of octets copied, excluding the terminator.
Return values
0The field was absent, empty, or cap left no room.
Precondition
cap is at least one, so a terminator always fits.
dst does not overlap src.
Postcondition
dst is NUL-terminated.
At most cap - 1 octets were copied.
Note
Pure copying; safe from any context.
Example:
ev.ssid_len = priv_c6link_copy_str(ev.ssid, sizeof ev.ssid, &body->ssid);
See also
priv_c6link_copy_mac
Since
0.1.0

Definition at line 37 of file ra8_c6link.c.

References RA8_PRIV.

Referenced by internal_c6link_rpc_ev_connected(), internal_c6link_rpc_ev_disconnected(), internal_c6link_take_ap(), and internal_c6link_take_fw().

◆ priv_c6link_dispatch()

bool priv_c6link_dispatch ( ra8_c6link_t * link,
const ra8_c6link_rx_view_t * view )
nodiscard

Route one well-formed received frame to whatever understands it.

Control-plane frames go to the RPC decoder, station and access-point frames to the Ethernet receive callback, and everything else is counted. ESP_PRIV_IF frames are counted rather than decoded: this co-processor build transmits its only privileged frame with a checksum that does not match its own header (#529), so a conformant host never sees a valid one.

Parameters
[in,out]linkOpen handle; must be non-null.
[in]viewPayload location from the classifier; must be non-null.
Returns
true when the outstanding wait was satisfied and the pump should stop.
Return values
trueThe awaited answer arrived.
falseKeep clocking.
Precondition
The frame classified as data, so view is populated.
The link's receive transaction still holds the frame.
Postcondition
Exactly one consumer was offered the payload.
The running counters reflect where it went.
Note
Not thread-safe; runs inside the pump.
Example:
if (priv_c6link_dispatch(link, &view)) { break; }
See also
priv_c6link_pump
Since
0.1.0

Definition at line 87 of file ra8_c6link.c.

References ra8_c6link::cb_ctx, ra8_c6link_stats::eth_in, ra8_c6link_rx_view::if_type, ra8_c6link_rx_view::len, ra8_c6link_rx_view::offset, priv_c6link_rpc_consume(), RA8_PRIV, ra8_c6link::rx, ra8_c6link::rx_cb, ra8_c6link::stats, and ra8_c6link_stats::unrouted.

Referenced by internal_c6link_pump_receive().

◆ priv_c6link_emit()

void priv_c6link_emit ( ra8_c6link_t * link,
const ra8_c6link_event_t * ev )

Deliver one decoded announcement to the registered callback.

Lives in ra8_c6link.c beside the rest of the handle's state, and is called from the RPC decoder once it has turned an Event_* message into a first-party record.

Parameters
[in,out]linkOpen handle; must be non-null.
[in]evDecoded announcement; must be non-null.
Returns
Nothing.
Precondition
ev is fully populated for its kind.
The callback, if any, does not re-enter the link.
Postcondition
The announcement counter advanced.
boot_seen is set when ev is the boot announcement.
Note
Not thread-safe; runs inside the pump.
Example:
priv_c6link_emit(link, &ev);
See also
ra8_c6link_event_cb_t
Since
0.1.0

Definition at line 71 of file ra8_c6link.c.

References ra8_c6link::boot_seen, ra8_c6link::cb_ctx, ra8_c6link::event_cb, ra8_c6link_stats::events, k_ra8_c6link_event_boot, ra8_c6link_event::kind, RA8_PRIV, and ra8_c6link::stats.

Referenced by internal_c6link_rpc_event().

◆ ra8_c6link_await_ready()

ra8_err_t ra8_c6link_await_ready ( ra8_c6link_t * link,
uint16_t max_transactions,
ra8_c6link_fw_version_t * out )
nodiscard

Announce this host and prove the co-processor is answering.

Transmits the privileged host-capabilities frame – upstream's send_slave_config(), byte for byte – drains the few transactions behind LEGACY-OK: send_slave_config() is the upstream esp-hosted symbol name it so anything the co-processor volunteers reaches the event callback, and then decides readiness by asking a question and getting an answer: one identity exchange, whose reply is handed back in out.

Readiness is deliberately not the boot event. Event_ESPInit is emitted once, when the co-processor boots. On this bench the ESP32-C6 has its own supply, so resetting the RA8 does not reboot it and that event is long gone – it was consumed by whichever application was clocking the bus when it fired. A facade that waited for it therefore worked exactly once, on a freshly-flashed co-processor, and timed out on every run after. Waiting on a one-shot announcement to decide a steady-state property is the same defect #529 records against the ESP_PRIV_IF frame, wearing the RPC layer's clothes; the fix is to stop inferring liveness and measure it.

The announcement is still sent, because a co-processor that has just booted services no RPC until the host has introduced itself. Sending it to one that is already up is harmless – it re-states capabilities that have not changed.

Parameters
[in,out]linkOpen handle; must be non-null.
[in]max_transactionsTransactions the announcement phase may clock; must be non-zero. See k_ra8_c6link_announce_transfers.
[out]outReceives the co-processor's identity; must be non-null.
Returns
ra8_err_t Error code.
Return values
k_ra8_okThe co-processor answered; out is populated.
k_ra8_err_null_ptrlink or out was null.
k_ra8_err_not_initializedlink is not open.
k_ra8_err_invalid_argmax_transactions was zero.
k_ra8_err_busyA payload is already staged on link.
k_ra8_err_invalid_sizeThe capabilities frame would not fit, which is a build-time impossibility and therefore a corrupted handle.
k_ra8_err_timeoutThe identity request went unanswered.
k_ra8_err_hw_timeoutThe co-processor never armed HANDSHAKE, so no transaction was clocked.
k_ra8_err_spi_errorThe transport refused a transfer.
k_ra8_err_protocol_errorThe answer arrived malformed.
Precondition
The transport is up.
The caller has no payload staged on link.
Postcondition
On success out holds the identity and the link is usable.
At most max_transactions transactions were clocked announcing, plus k_ra8_c6link_rpc_transfers probing.
Note
Not thread-safe; it pumps.
A boot event that does arrive during the announcement phase still reaches the event callback as k_ra8_c6link_event_boot. It is reportable; it is simply not load-bearing.
Example:
&link, (uint16_t)k_ra8_c6link_announce_transfers, &fw);
ra8_err_codes_t ra8_err_t
Canonical error-return type used by every ra8-firmware API.
Definition ra8_err.h:546
See also
ra8_c6link_fw_version
ra8_c6link_poll
Since
0.1.0
NASA Power of 10 Compliance:
  • Rule 2: both phases are bounded by explicit transaction budgets.
  • Rule 5: four preconditions and two postconditions are checked.

Definition at line 233 of file ra8_c6link.c.

References k_ra8_c6link_caps_bytes, k_ra8_c6link_header_bytes, k_ra8_err_busy, k_ra8_err_invalid_arg, k_ra8_err_invalid_size, k_ra8_err_not_initialized, k_ra8_err_null_ptr, k_ra8_ok, ra8_c6link::open, priv_c6link_caps(), priv_c6link_pump(), ra8_c6link_fw_version(), ra8_c6link::tx, ra8_c6link::tx_if, and ra8_c6link::tx_len.

Referenced by c6_join_phase_ready(), c6_wifi_phase_ready(), internal_c6_cam_prepare_link(), internal_c6link_op_open(), and internal_open_and_join().

◆ ra8_c6link_close()

ra8_err_t ra8_c6link_close ( ra8_c6link_t * link)
nodiscard

Release a link handle.

Drops the transport binding, the callbacks and the arena reference, and marks the handle closed. The transport itself is not torn down – whoever brought it up owns that.

Parameters
[in,out]linkHandle to release; must be non-null and open.
Returns
ra8_err_t Error code.
Return values
k_ra8_okThe handle is closed.
k_ra8_err_null_ptrlink was null.
k_ra8_err_not_initializedlink was not open.
Precondition
No pump is running against link.
The caller no longer needs the last fault or counters.
Postcondition
The handle reports closed.
No callback registered through link is invoked again.
Note
Not thread-safe; close from the same context that opened.
Example:
static ra8_c6link_t s_link
Definition c6_cam_app.c:44
See also
ra8_c6link_open
Since
0.1.0

Definition at line 178 of file ra8_c6link.c.

References ra8_c6link::arena, ra8_c6link::cb_ctx, ra8_c6link::event_cb, k_ra8_err_not_initialized, k_ra8_err_null_ptr, k_ra8_ok, ra8_c6link::open, ra8_c6link::rx_cb, ra8_c6link::stats, ra8_c6link::transport, ra8_c6link::tx_len, and ra8_c6link::wait.

Referenced by internal_c6link_op_close(), and internal_run().

◆ ra8_c6link_eth_send()

ra8_err_t ra8_c6link_eth_send ( ra8_c6link_t * link,
const uint8_t * frame,
uint16_t len )
nodiscard

Hand one 802.3 frame to the co-processor for transmission.

Stages the frame on the station interface and pumps until a transaction has carried it out. The data plane needs no protobuf: the frame is the payload, behind the same twelve-byte header the control plane uses.

Parameters
[in,out]linkOpen handle; must be non-null.
[in]frameFrame bytes, starting at the destination address; must be non-null.
[in]lenFrame length; must be non-zero and at most k_ra8_c6link_max_payload.
Returns
ra8_err_t Error code.
Return values
k_ra8_okThe frame was clocked out.
k_ra8_err_null_ptrlink or frame was null.
k_ra8_err_not_initializedlink is not open.
k_ra8_err_invalid_sizelen was zero or above the payload cap.
k_ra8_err_busyAnother payload is already staged.
k_ra8_err_hw_timeoutThe co-processor never armed HANDSHAKE.
k_ra8_err_spi_errorThe transport refused a transfer.
Precondition
The station has been started; frames sent before that are discarded by the co-processor.
len bytes are readable at frame.
Postcondition
On success the frame has left this host.
Anything the co-processor sent during the same transactions was delivered to the registered callbacks.
Note
Not thread-safe; it pumps.
Warning
There is no transmit queue: one frame is staged at a time, which is what an IP driver that transmits from one thread needs and no more.
Example:
(void)ra8_c6link_eth_send(&link, packet, packet_len);
See also
ra8_c6link_rx_cb_t
Since
0.1.0

Definition at line 338 of file ra8_c6link.c.

References k_ra8_c6link_header_bytes, k_ra8_c6link_hs_giveup, k_ra8_c6link_max_payload, k_ra8_err_busy, k_ra8_err_hw_timeout, k_ra8_err_invalid_size, k_ra8_err_not_initialized, k_ra8_err_null_ptr, k_ra8_ok, ra8_c6link::open, priv_c6link_pump(), ra8_c6link::tx, ra8_c6link::tx_if, and ra8_c6link::tx_len.

Referenced by internal_handle_send().

◆ ra8_c6link_fw_version()

ra8_err_t ra8_c6link_fw_version ( ra8_c6link_t * link,
ra8_c6link_fw_version_t * out )
nodiscard

Ask the co-processor to identify itself.

Issues Req_GetCoprocessorFwVersion and decodes the answer. This is the cheapest complete proof that the whole stack works – framing, checksum, TLV, protobuf, correlation – because the answer is a fact the host can check rather than merely receive.

Parameters
[in,out]linkOpen handle; must be non-null.
[out]outIdentity to fill; must be non-null.
Returns
ra8_err_t Error code.
Return values
k_ra8_okout holds the co-processor's answer.
k_ra8_err_null_ptrlink or out was null.
k_ra8_err_not_initializedlink is not open.
k_ra8_err_busyA request is already outstanding on link.
k_ra8_err_timeoutThe co-processor did not answer within the budget.
k_ra8_err_hw_timeoutThe co-processor never armed HANDSHAKE, so no transaction was clocked.
k_ra8_err_protocol_errorThe answer arrived but reported a failure.
k_ra8_err_spi_errorThe transport refused a transfer.
Precondition
The transport is up.
No other request is outstanding on link.
Postcondition
On success every field of out is set from the answer.
On failure the handle's last fault names this request.
Note
Not thread-safe; it pumps.
Example:
(void)ra8_c6link_fw_version(&link, &fw);
See also
ra8_c6link_last_fault
Since
0.1.0

Definition at line 310 of file ra8_c6link.c.

References internal_c6link_take_fw(), k_ra8_err_not_initialized, k_ra8_err_null_ptr, ra8_c6link::open, and priv_c6link_rpc_call().

Referenced by ra8_c6link_await_ready().

◆ ra8_c6link_is_open()

bool ra8_c6link_is_open ( const ra8_c6link_t * link)
nodiscard

Report whether a handle is currently open.

Parameters
[in]linkHandle to inspect; null reads as closed.
Returns
true when ra8_c6link_open has succeeded and no close has run since.
Return values
trueThe handle is usable.
falseThe handle is null, never opened, or closed.
Precondition
None; safe at any time, including before any open.
The caller tolerates a value a concurrent close may stale.
Postcondition
No state is modified.
The returned value reflects the flag at the moment of the read.
Note
Safe from any context; a single aligned load.
Example:
See also
ra8_c6link_open
Since
0.1.0

Definition at line 198 of file ra8_c6link.c.

References ra8_c6link::open.

Referenced by ra8_c6link_wifi_ap_info(), ra8_c6link_wifi_join(), ra8_c6link_wifi_leave(), ra8_c6link_wifi_mac(), ra8_c6link_wifi_start(), and ra8_c6link_wifi_stop().

◆ ra8_c6link_last_fault()

ra8_err_t ra8_c6link_last_fault ( const ra8_c6link_t * link,
ra8_c6link_fault_t * out )
nodiscard

Report the last request that failed on this link.

Parameters
[in]linkOpen handle; must be non-null.
[out]outFault record to fill; must be non-null.
Returns
ra8_err_t Error code.
Return values
k_ra8_okout holds the record; an all-zero record means no request has failed since the handle was opened.
k_ra8_err_null_ptrlink or out was null.
Precondition
The handle has been opened at least once.
The caller reads the record before issuing another request, which would overwrite it.
Postcondition
No link state is modified.
out is fully written, including on the no-fault path.
Note
Safe from any context; it copies two words.
Example:
(void)ra8_c6link_last_fault(&link, &f);
See also
ra8_c6link_fault
Since
0.1.0

Definition at line 203 of file ra8_c6link.c.

References ra8_c6link::fault, k_ra8_err_null_ptr, and k_ra8_ok.

Referenced by c6_join_report_fault(), and c6_wifi_report_fault().

◆ ra8_c6link_open()

ra8_err_t ra8_c6link_open ( ra8_c6link_t * link,
const ra8_c6link_cfg_t * cfg )
nodiscard

Bind a transport to a link handle and make it usable.

Validates the seam and the arena, copies both into the handle, and resets every counter. No hardware is touched: bringing the transport itself up (pin routing, bus open, clocking) belongs to the backend that fills the seam, and happens before this call.

Parameters
[out]linkHandle to initialise; must be non-null.
[in]cfgConfiguration; must be non-null with every transport row filled and an arena of at least k_ra8_c6link_arena_min bytes.
Returns
ra8_err_t Error code.
Return values
k_ra8_okThe link is open.
k_ra8_err_null_ptrlink, cfg, a transport row, or the arena pointer was null.
k_ra8_err_invalid_sizearena_bytes is below k_ra8_c6link_arena_min.
k_ra8_err_invalid_statelink is already open.
Precondition
The transport backend is already up and can clock a transaction.
link is zero-initialised, or has been closed.
Postcondition
On success the handle reports open and every counter is zero.
On failure link is not modified.
Note
Not thread-safe; open once from a single-threaded bring-up path.
Warning
The arena and everything the transport seam points at must outlive the link.
Example:
if (ra8_c6link_open(&s_link, &cfg) != k_ra8_ok) { report(); }
@ k_ra8_ok
Success – operation completed with all postconditions satisfied.
Definition ra8_err.h:119
See also
ra8_c6link_close
Since
0.1.0
NASA Power of 10 Compliance:
  • Rule 3: no allocation; the arena is the caller's.
  • Rule 5: four preconditions and two postconditions are checked.

Definition at line 146 of file ra8_c6link.c.

References ra8_c6link::arena, ra8_c6link_cfg::arena, ra8_c6link::arena_bytes, ra8_c6link_cfg::arena_bytes, ra8_c6link::arena_last, ra8_c6link::arena_used, ra8_c6link::boot_seen, ra8_c6link::cb_ctx, ra8_c6link_cfg::cb_ctx, ra8_c6link::event_cb, ra8_c6link_cfg::event_cb, ra8_c6link::fault, internal_c6link_check_cfg(), k_ra8_err_invalid_state, k_ra8_err_null_ptr, k_ra8_ok, ra8_c6link::next_uid, ra8_c6link::open, ra8_c6link::rx_cb, ra8_c6link_cfg::rx_cb, ra8_c6link::stats, ra8_c6link::transport, ra8_c6link_cfg::transport, ra8_c6link::tx_if, ra8_c6link::tx_len, and ra8_c6link::wait.

Referenced by c6_join_open_link(), c6_wifi_open_link(), internal_c6_cam_open_link(), internal_c6link_op_open(), and internal_open_and_join().

◆ ra8_c6link_poll()

ra8_err_t ra8_c6link_poll ( ra8_c6link_t * link,
uint16_t max_transactions,
ra8_c6link_stats_t * stats )
nodiscard

Clock transactions, delivering whatever the co-processor sends.

The pump. Each iteration waits for HANDSHAKE, transmits either a staged payload or an idle filler frame, clocks k_ra8_c6link_frame_bytes both ways, and classifies what came back: filler is counted, malformed and checksum-failing frames are counted and dropped, and well-formed frames are routed by interface – control plane to the RPC decoder, station traffic to the receive callback.

Call it to drive the link when no request is outstanding: to drain events, to receive Ethernet frames, or to give a staged transmit somewhere to go. Requests issued through this library pump internally and need no help.

Parameters
[in,out]linkOpen handle; must be non-null.
[in]max_transactionsTransactions this call may clock; must be non-zero.
[out]statsCounters describing the run, or null to discard them.
Returns
ra8_err_t Error code.
Return values
k_ra8_okThe pump ran; stats says what happened.
k_ra8_err_null_ptrlink was null.
k_ra8_err_not_initializedlink is not open.
k_ra8_err_invalid_argmax_transactions was zero.
k_ra8_err_hw_timeoutHANDSHAKE never went active, so not one transaction was clocked.
k_ra8_err_spi_errorThe transport refused a transfer.
Precondition
The transport is up and no other context is driving it.
Callbacks registered at open are safe to invoke now.
Postcondition
At most max_transactions transactions were clocked.
stats, when non-null, holds the counts for exactly this call.
Note
Not thread-safe; one pump at a time owns the transport.
Warning
Callbacks run inside this call and must not re-enter the link.
Example:
(void)ra8_c6link_poll(&link, 16U, &st);
See also
ra8_c6link_stats
Since
0.1.0
NASA Power of 10 Compliance:
  • Rule 2: the transaction loop is bounded by max_transactions and the handshake wait by k_ra8_c6link_hs_wait_ms.
  • Rule 5: three preconditions and two postconditions are checked.

Definition at line 212 of file ra8_c6link.c.

References k_ra8_err_invalid_arg, k_ra8_err_not_initialized, k_ra8_err_null_ptr, ra8_c6link::open, and priv_c6link_pump().

Referenced by c6_join_wait_connected(), c6_wifi_phase_station(), internal_c6_cam_wait_connected(), internal_c6link_op_service(), internal_rx_worker_entry(), and internal_wait_connected().