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

Shared contract for the esp-hosted RPC round-trip application. More...

#include <stddef.h>
#include <stdint.h>
#include "esp_hosted_header.h"
#include "port_esp_hosted_host_spi.h"
#include "ra8_err.h"
Include dependency graph for c6_fwver.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

union  c6_fwver_frame
 One esp-hosted transaction buffer, addressable either way. More...
struct  c6_fwver_pump_stats
 What one call to c6_fwver_link_pump actually did on the wire. More...

Typedefs

typedef union c6_fwver_frame c6_fwver_frame_t
typedef struct c6_fwver_pump_stats c6_fwver_pump_stats_t
typedef bool(* c6_fwver_sink_t) (uint8_t if_type, uint8_t if_num, const uint8_t *payload, uint16_t len)
 Receiver for one well-formed frame the co-processor sent.

Enumerations

enum  c6_fwver_cfg_t : uint32_t {
  k_c6_fwver_uart_baud = 115200U ,
  k_c6_fwver_sck_hz = 5000000U ,
  k_c6_fwver_edge_poll_ms = 2U ,
  k_c6_fwver_boot_wait_ms = 200U ,
  k_c6_fwver_heartbeat_ms = 5000U ,
  k_c6_fwver_dma_align = 64U ,
  k_c6_fwver_worker_stack = 8192U ,
  k_c6_fwver_worker_prio = 8U ,
  k_c6_fwver_rpc_uid = 1U
}
 Link, thread and pacing parameters this application chooses. More...
enum  c6_fwver_fmt_t : uint16_t {
  k_c6_fwver_str_max = 256U ,
  k_c6_fwver_dec_radix = 10U ,
  k_c6_fwver_dec_digits = 10U ,
  k_c6_fwver_hex_digits = 8U ,
  k_c6_fwver_hex_bits = 4U ,
  k_c6_fwver_hex_mask = 0x0FU ,
  k_c6_fwver_hex_alpha = 10U ,
  k_c6_fwver_hex_byte = 2U ,
  k_c6_fwver_hex_word = 4U ,
  k_c6_fwver_text_max = 32U
}
 Bounds for the console formatters in src/c6_fwver_console.c. More...
enum  c6_fwver_link_t : uint16_t {
  k_c6_fwver_frame_bytes = (uint16_t)MAX_TRANSPORT_BUFFER_SIZE ,
  k_c6_fwver_max_transfers = 64U ,
  k_c6_fwver_hs_wait_ms = 200U ,
  k_c6_fwver_hs_giveup = 3U ,
  k_c6_fwver_hs_poll_ms = 1U ,
  k_c6_fwver_gap_ms = 2U ,
  k_c6_fwver_tx_max = 512U
}
 Frame geometry and pump budgets the transaction layer works to. More...

Functions

void c6_fwver_puts (const char *text)
 Write a NUL-terminated string to the board console.
void c6_fwver_put_u32 (uint32_t value)
 Emit an unsigned 32-bit value in decimal.
void c6_fwver_put_i32 (int32_t value)
 Emit a signed 32-bit value in decimal.
void c6_fwver_put_hex (uint32_t value, uint8_t digits)
 Emit a value as a fixed-width lower-case hexadecimal field.
void c6_fwver_put_text (const uint8_t *text, size_t len)
 Emit a length-counted byte range as printable text.
void c6_fwver_print_banner (uint32_t cpuclk_hz, uint32_t pclka_hz)
 Print the banner: identity, clocks and SPI parameters.
void c6_fwver_print_pump (const char *label, const c6_fwver_pump_stats_t *stats)
 Print what one pump did, as one console line.
ra8_err_t c6_fwver_link_pump (uint8_t if_type, uint8_t if_num, const uint8_t *payload, uint16_t payload_len, uint16_t max_transfers, c6_fwver_sink_t sink, c6_fwver_pump_stats_t *stats)
 Clock full-duplex transactions until the sink is satisfied.
ra8_err_t c6_fwver_priv_host_caps (uint8_t *out, uint16_t cap, uint16_t *out_len)
 Build the host-capabilities frame the reference host sends first.
bool c6_fwver_priv_consume (uint8_t if_type, uint8_t if_num, const uint8_t *payload, uint16_t len)
 Decode an ESP_PRIV_IF frame and report what it announced.
uint32_t c6_fwver_priv_init_version (void)
 Report the version the boot INIT event announced, if one arrived.
ra8_err_t c6_fwver_rpc_request (uint8_t *out, uint16_t cap, uint16_t *out_len)
 Build the TLV-wrapped RPC firmware-version request.
bool c6_fwver_rpc_consume (uint8_t if_type, uint8_t if_num, const uint8_t *payload, uint16_t len)
 Decode an ESP_SERIAL_IF frame as the awaited RPC response.
bool c6_fwver_rpc_report (void)
 Print the recorded response and decide the run's verdict.
bool c6_fwver_dispatch (uint8_t if_type, uint8_t if_num, const uint8_t *payload, uint16_t len)
 Route a received frame to the module that understands it.

Detailed Description

Shared contract for the esp-hosted RPC round-trip application.

Tag
[Ring 6 / APP] {World: S}

c6_hosted_init proved one transaction reaches the co-processor and comes back framed. This application proves the layer above it: a request that goes up, is parsed by the co-processor, and is answered with a populated response whose fields are then checked. The request chosen is RPC_ID__Req_GetCoprocessorFwVersion, because its answer is a fact this side already knows independently – the vendored host driver's own version – so the verdict can be a comparison rather than a shrug.

One module per concern, all driven by main.c:

  • src/c6_fwver_console.c – bounded console formatters, so the image links no newlib printf.
  • src/c6_fwver_link.c – the transaction pump: build a payload header around a payload, clock full-duplex transactions through the port's _h_do_bus_transfer, validate each received frame and hand the good ones to a sink.
  • src/c6_fwver_priv.c – the ESP_PRIV_IF control channel: the host-capabilities frame the reference host sends first, and the decode of the co-processor's boot INIT event.
  • src/c6_fwver_rpc.c – the ESP_SERIAL_IF RPC channel: the protobuf request, its TLV envelope, the response decode and the verdict.

Every protocol size and identifier is read from the vendored esp-hosted headers rather than restated, and every pin identity is read from port/esp-hosted/inc/ra8_esp_hosted_pins.h. This file holds only what an application genuinely owns: pacing, buffer bounds and formatter widths.

Since
0.1.0

Definition in file c6_fwver.h.

Typedef Documentation

◆ c6_fwver_frame_t

◆ c6_fwver_pump_stats_t

◆ c6_fwver_sink_t

typedef bool(* c6_fwver_sink_t) (uint8_t if_type, uint8_t if_num, const uint8_t *payload, uint16_t len)

Receiver for one well-formed frame the co-processor sent.

A function pointer rather than a fixed call keeps the transaction layer ignorant of the protocol layers above it (Dependency Inversion; NASA Power of 10 Rule 9 permits function pointers for exactly this).

Parameters
[in]if_typeInterface type from the received payload header.
[in]if_numInterface number from the received payload header.
[in]payloadFrame payload; never null, never zero length.
[in]lenPayload length in bytes, at most MAX_PAYLOAD_SIZE.
Returns
true to stop the pump, false to keep clocking.
Note
Runs on the pumping thread and must not start a transaction of its own; the bus is in use for the duration of the call.
Since
0.1.0

Definition at line 237 of file c6_fwver.h.

Enumeration Type Documentation

◆ c6_fwver_cfg_t

enum c6_fwver_cfg_t : uint32_t

Link, thread and pacing parameters this application chooses.

Only values an application owns live here. NASA Power of 10 Rule 3 forbids allocation after initialisation and this image has no heap, so the worker stack and the transaction-buffer alignment are sized here alongside the link timing.

Invariant
k_c6_fwver_sck_hz is the bit rate c6_hosted_init was proven at on 2026-07-28, so this application changes one variable at a time relative to that run.
k_c6_fwver_edge_poll_ms is non-zero; the port's software edge detector arms a ThreadX timer, which rejects a zero tick.
Example:
cfg.sck_hz = (uint32_t)k_c6_fwver_sck_hz;
@ k_c6_fwver_sck_hz
SPI bit rate; the rate the port ran at on silicon in the c6_hosted_init bring-up.
Definition c6_fwver.h:72
See also
ra8_esp_hosted_port_cfg_t
Since
0.1.0
Enumerator
k_c6_fwver_uart_baud 

Console rate, 8N1, over the J-Link OB VCOM.

k_c6_fwver_sck_hz 

SPI bit rate; the rate the port ran at on silicon in the c6_hosted_init bring-up.

k_c6_fwver_edge_poll_ms 

Poll period for a side-band pin with no ICU channel.

k_c6_fwver_boot_wait_ms 

Settling delay before the first transaction.

k_c6_fwver_heartbeat_ms 

Heartbeat gap after the verdict, in milliseconds and therefore in ThreadX ticks.

k_c6_fwver_dma_align 

Transaction-buffer alignment, in bytes.

k_c6_fwver_worker_stack 

Worker-thread stack, in bytes.

The protobuf decoder recurses through nested messages, so this is double what c6_hosted_init needs.

k_c6_fwver_worker_prio 

Worker priority and preemption threshold.

k_c6_fwver_rpc_uid 

UID stamped on the request; the response must carry it back unchanged.

Definition at line 70 of file c6_fwver.h.

◆ c6_fwver_fmt_t

enum c6_fwver_fmt_t : uint16_t

Bounds for the console formatters in src/c6_fwver_console.c.

The image links no newlib printf, so the serialisers do their own digit extraction; every loop they run is bounded by a value from this enumeration, which is what satisfies NASA Power of 10 Rule 2.

Invariant
k_c6_fwver_dec_digits holds the widest 32-bit decimal value.
k_c6_fwver_hex_digits holds the widest 32-bit hex value.
Example:
void c6_fwver_put_hex(uint32_t value, uint8_t digits)
Emit a value as a fixed-width lower-case hexadecimal field.
@ k_c6_fwver_hex_word
Hex digits printed for a 16-bit field.
Definition c6_fwver.h:112
See also
c6_fwver_put_u32
Since
0.1.0
Enumerator
k_c6_fwver_str_max 

Longest string the console helper emits.

k_c6_fwver_dec_radix 

Decimal radix.

k_c6_fwver_dec_digits 

Digits in the widest 32-bit decimal value.

k_c6_fwver_hex_digits 

Digits in the widest 32-bit hex value.

k_c6_fwver_hex_bits 

Bits per hexadecimal digit.

k_c6_fwver_hex_mask 

Nibble mask.

k_c6_fwver_hex_alpha 

First nibble value spelled with a letter.

k_c6_fwver_hex_byte 

Hex digits printed for a byte-wide field.

k_c6_fwver_hex_word 

Hex digits printed for a 16-bit field.

k_c6_fwver_text_max 

Longest co-processor-supplied string echoed to the console; anything longer is truncated rather than trusted.

Definition at line 103 of file c6_fwver.h.

◆ c6_fwver_link_t

enum c6_fwver_link_t : uint16_t

Frame geometry and pump budgets the transaction layer works to.

The frame size is read from the vendored transport header rather than restated. The budgets are this application's own: they exist so every loop in the pump has a statically provable bound (NASA Power of 10 Rule 2) and so a co-processor that never answers produces a verdict instead of a hang.

Invariant
k_c6_fwver_frame_bytes is exactly the byte count the co-processor clocks in one full-duplex transaction.
k_c6_fwver_max_transfers x k_c6_fwver_hs_wait_ms bounds the worst-case wall time of one pump, so the verdict always arrives.
Example:
(void)c6_fwver_link_pump(ESP_SERIAL_IF, 0U, req, req_len,
(uint16_t)k_c6_fwver_max_transfers, sink, &stats);
ra8_err_t c6_fwver_link_pump(uint8_t if_type, uint8_t if_num, const uint8_t *payload, uint16_t payload_len, uint16_t max_transfers, c6_fwver_sink_t sink, c6_fwver_pump_stats_t *stats)
Clock full-duplex transactions until the sink is satisfied.
@ k_c6_fwver_max_transfers
Transactions one pump may clock before giving up.
Definition c6_fwver.h:141
See also
c6_fwver_link_pump
Since
0.1.0
Enumerator
k_c6_fwver_frame_bytes 

Bytes clocked in one full-duplex transaction.

k_c6_fwver_max_transfers 

Transactions one pump may clock before giving up.

k_c6_fwver_hs_wait_ms 

Milliseconds to wait for HANDSHAKE before abandoning a transaction.

k_c6_fwver_hs_giveup 

Consecutive HANDSHAKE timeouts after which the pump stops.

A co-processor that has not armed the line three times running is not there, and spending the rest of the transaction budget re-asking proves nothing while turning "absent" into a half-minute hang – which is what a bench with the harness unplugged, and ra8_emulator with no C6 modelled at all, both look like.

k_c6_fwver_hs_poll_ms 

Sampling period while waiting for HANDSHAKE.

k_c6_fwver_gap_ms 

Settling gap between consecutive transactions.

k_c6_fwver_tx_max 

Bound on any payload this application transmits: the packed RPC request and its TLV envelope are two orders of magnitude smaller, and the host-capabilities frame is fifteen bytes.

Definition at line 138 of file c6_fwver.h.

Function Documentation

◆ c6_fwver_dispatch()

bool c6_fwver_dispatch ( uint8_t if_type,
uint8_t if_num,
const uint8_t * payload,
uint16_t len )

Route a received frame to the module that understands it.

Parameters
[in]if_typeInterface type from the received header.
[in]if_numInterface number from the received header.
[in]payloadFrame payload; null is ignored.
[in]lenPayload length in bytes.
Returns
true when the pump should stop.
Return values
trueThe RPC layer accepted the awaited response.
falseEverything else, including announcements.
Precondition
The console is up.
len bytes are readable at payload.
Postcondition
Exactly one module was offered the frame.
No application state is modified beyond that module's own.
Note
Matches c6_fwver_sink_t; it is the sink every pump is given.
See also
c6_fwver_link_pump
Since
0.1.0

Definition at line 539 of file c6_fwver_rpc.c.

References c6_fwver_priv_consume(), c6_fwver_put_u32(), c6_fwver_puts(), and c6_fwver_rpc_consume().

Referenced by c6_fwver_phase_caps(), and c6_fwver_phase_request().

◆ c6_fwver_link_pump()

ra8_err_t c6_fwver_link_pump ( uint8_t if_type,
uint8_t if_num,
const uint8_t * payload,
uint16_t payload_len,
uint16_t max_transfers,
c6_fwver_sink_t sink,
c6_fwver_pump_stats_t * stats )
nodiscard

Clock full-duplex transactions until the sink is satisfied.

The pump is this application's stand-in for the vendored spi_transaction_task, reduced to what a bring-up needs: it transmits at most one payload, then keeps clocking filler frames so the co-processor has transactions to answer in. Each iteration waits for HANDSHAKE, builds either the pending payload frame or an ESP_MAX_IF filler, clocks _h_do_bus_transfer, and classifies what came back. Frames that are well-formed and carry a payload go to sink; filler and malformed frames are counted and dropped.

Parameters
[in]if_typeInterface type for the transmitted payload, from esp_hosted_if_type_t. Ignored when payload_len is zero.
[in]if_numInterface number for the transmitted payload, 0..15.
[in]payloadPayload to transmit once, or null to pump filler only.
[in]payload_lenLength of payload in bytes; must be zero when payload is null and at most k_c6_fwver_tx_max otherwise.
[in]max_transfersTransactions this call may clock; must be non-zero.
[in]sinkReceiver for well-formed frames, or null to count only.
[out]statsCounters describing the run; must be non-null.
Returns
ra8_err_t Error code.
Return values
k_ra8_okThe pump ran; stats says what happened.
k_ra8_err_null_ptrstats was null, or payload_len was non-zero with a null payload.
k_ra8_err_invalid_argpayload_len exceeds k_c6_fwver_tx_max, or max_transfers was zero.
k_ra8_err_not_initializedThe esp-hosted port is not up, so the vtable behind g_h cannot be called.
k_ra8_err_hw_timeoutHANDSHAKE never went active, so not one transaction was clocked.
k_ra8_err_spi_errorA bus transfer did not return RET_OK.
Precondition
ra8_esp_hosted_port_init returned k_ra8_ok.
No other context is driving the SPI bus.
Postcondition
At most max_transfers transactions were clocked.
stats holds the counts for exactly this call.
Note
Not thread-safe; one pump at a time owns the bus.
Warning
The sink runs inside the pump, so it must not start a transaction.
Example:
(void)c6_fwver_link_pump((uint8_t)ESP_SERIAL_IF, 0U, req, req_len,
bool c6_fwver_dispatch(uint8_t if_type, uint8_t if_num, const uint8_t *payload, uint16_t len)
Route a received frame to the module that understands it.
struct c6_fwver_pump_stats c6_fwver_pump_stats_t
See also
c6_fwver_pump_stats
Since
0.1.0
NASA Power of 10 Compliance:
  • Rule 2: the transaction loop is bounded by max_transfers and the HANDSHAKE wait by k_c6_fwver_hs_wait_ms.
  • Rule 5: four preconditions and two postconditions are checked.

Definition at line 395 of file c6_fwver_link.c.

References c6_fwver_pump_stats::bus_error, c6_fwver_pump_check(), c6_fwver_rx_dispatch(), c6_fwver_tx_filler(), c6_fwver_tx_frame(), c6_fwver_wait_handshake(), g_h, c6_fwver_pump_stats::hs_timeouts, k_c6_fwver_frame_bytes, k_c6_fwver_gap_ms, k_c6_fwver_hs_giveup, k_ra8_err_hw_timeout, k_ra8_err_spi_error, k_ra8_ok, RET_OK, s_c6_fwver_rx, s_c6_fwver_tx, c6_fwver_pump_stats::sink_stopped, and c6_fwver_pump_stats::transfers.

Referenced by c6_fwver_phase_caps(), and c6_fwver_phase_request().

◆ c6_fwver_print_banner()

void c6_fwver_print_banner ( uint32_t cpuclk_hz,
uint32_t pclka_hz )

Print the banner: identity, clocks and SPI parameters.

Parameters
[in]cpuclk_hzLive CPUCLK0 rate in hertz.
[in]pclka_hzLive PCLKA rate in hertz, the SCI baud-clock source.
Returns
Nothing.
Precondition
The console is up.
Both rates were read from the CGC rather than assumed.
Postcondition
Three banner lines were emitted.
No application state is modified.
Note
The SPI mode printed is the co-processor's: the C6 image in coprocessor/esp32c6/ is built with CONFIG_ESP_SPI_MODE=3 and the port opens the bus to match.
See also
c6_fwver_link_pump
Since
0.1.0

Definition at line 128 of file c6_fwver_console.c.

References c6_fwver_put_u32(), c6_fwver_puts(), k_c6_fwver_frame_bytes, k_c6_fwver_sck_hz, k_ra8_board_pmod1_sci_channel, and MAX_PAYLOAD_SIZE.

Referenced by main().

◆ c6_fwver_print_pump()

void c6_fwver_print_pump ( const char * label,
const c6_fwver_pump_stats_t * stats )

Print what one pump did, as one console line.

Parameters
[in]labelField name printed before the counters; null prints nothing at all rather than being dereferenced.
[in]statsCounters filled in by c6_fwver_link_pump; null prints nothing.
Returns
Nothing.
Precondition
The console is up.
stats came from a completed pump.
Postcondition
Exactly one line was emitted, or none on a null argument.
No application state is modified.
Note
Every counter is printed, including the zero ones: a zero bad_checksum beside a non-zero transfers is itself the evidence that the link is clean.
See also
c6_fwver_pump_stats
Since
0.1.0

Definition at line 147 of file c6_fwver_console.c.

References c6_fwver_pump_stats::bad_checksum, c6_fwver_pump_stats::bus_error, c6_fwver_put_u32(), c6_fwver_puts(), c6_fwver_pump_stats::frames, c6_fwver_pump_stats::hs_timeouts, c6_fwver_pump_stats::idle, c6_fwver_pump_stats::ifnum_defect, c6_fwver_pump_stats::malformed, c6_fwver_pump_stats::sink_stopped, and c6_fwver_pump_stats::transfers.

Referenced by c6_fwver_phase_caps(), and c6_fwver_phase_request().

◆ c6_fwver_priv_consume()

bool c6_fwver_priv_consume ( uint8_t if_type,
uint8_t if_num,
const uint8_t * payload,
uint16_t len )

Decode an ESP_PRIV_IF frame and report what it announced.

Walks the TLV list of an ESP_PRIV_EVENT_INIT event, printing the capability word, the firmware chip id and – the interesting one – the ESP_PRIV_FIRMWARE_VERSION tag, which carries the co-processor's own version as a little-endian 32-bit word. That is an independent second reading of the number the RPC round-trip asks for.

Parameters
[in]if_typeInterface type from the received header.
[in]if_numInterface number from the received header.
[in]payloadFrame payload; null is ignored.
[in]lenPayload length in bytes.
Returns
false always: an announcement is never a reason to stop pumping.
Return values
falseThe frame was decoded, ignored, or was not a priv frame.
Precondition
The console is up.
len bytes are readable at payload.
Postcondition
At most one line was emitted per recognised TLV.
The recorded init-event version is updated when the tag is present.
Note
Matches c6_fwver_sink_t so the pump can call it directly.
See also
c6_fwver_priv_init_version
Since
0.1.0

Definition at line 222 of file c6_fwver_priv.c.

References c6_fwver_priv_tlv(), c6_fwver_put_hex(), c6_fwver_put_u32(), c6_fwver_puts(), k_c6_fwver_hex_byte, k_c6_fwver_priv_evt_hdr, k_c6_fwver_priv_evt_len, k_c6_fwver_priv_evt_type, k_c6_fwver_priv_tlv_size, k_c6_fwver_priv_tlv_tag, and k_c6_fwver_priv_tlv_value.

Referenced by c6_fwver_dispatch().

◆ c6_fwver_priv_host_caps()

ra8_err_t c6_fwver_priv_host_caps ( uint8_t * out,
uint16_t cap,
uint16_t * out_len )
nodiscard

Build the host-capabilities frame the reference host sends first.

Byte-for-byte the TLV set the vendored transport_drv.c composes in send_slave_config() LEGACY-OK: upstream esp-hosted function name – host capabilities, the firmware chip id the host expects, the raw-throughput direction, and the two flow-control thresholds, behind an ESP_PRIV_EVENT_INIT event header.

Parameters
[out]outBuffer to fill; must be non-null.
[in]capBytes available at out.
[out]out_lenBytes written; must be non-null.
Returns
ra8_err_t Error code.
Return values
k_ra8_okThe frame was built and out_len is its length.
k_ra8_err_null_ptrout or out_len was null.
k_ra8_err_invalid_sizecap cannot hold the frame.
Precondition
cap bytes are writable at out.
The caller transmits the result on ESP_PRIV_IF, interface 0.
Postcondition
On success out_len is non-zero and at most cap.
On failure out is not modified.
Note
Pure formatting; touches no hardware and is safe from any thread.
See also
c6_fwver_priv_consume
Since
0.1.0

Definition at line 142 of file c6_fwver_priv.c.

References c6_fwver_priv_put_tlv(), H_TEST_RAW_TP_DIR, H_WIFI_TX_DATA_THROTTLE_HIGH_THRESHOLD, H_WIFI_TX_DATA_THROTTLE_LOW_THRESHOLD, k_c6_fwver_priv_evt_hdr, k_c6_fwver_priv_evt_len, k_c6_fwver_priv_evt_type, k_c6_fwver_priv_host_cap, k_c6_fwver_priv_tag_count, k_c6_fwver_priv_tlv_stride, k_ra8_err_invalid_size, k_ra8_err_null_ptr, and k_ra8_ok.

Referenced by c6_fwver_phase_caps().

◆ c6_fwver_priv_init_version()

uint32_t c6_fwver_priv_init_version ( void )
nodiscard

Report the version the boot INIT event announced, if one arrived.

Returns
The packed (major << 16) | (minor << 8) | patch word, or zero when no INIT event carrying the tag has been decoded.
Return values
0No ESP_PRIV_FIRMWARE_VERSION tag has been seen.
Precondition
None; safe to call before any frame has arrived.
The caller treats zero as "not observed", not as version 0.0.0.
Postcondition
No application state is modified.
The returned value reflects the last INIT event decoded.
Note
The co-processor queues this event once per boot, so a run that follows an earlier run without power-cycling the C6 will not see it.
See also
c6_fwver_priv_consume
Since
0.1.0

Definition at line 263 of file c6_fwver_priv.c.

References s_c6_fwver_priv_version.

Referenced by c6_fwver_rpc_print_crosscheck().

◆ c6_fwver_put_hex()

void c6_fwver_put_hex ( uint32_t value,
uint8_t digits )

Emit a value as a fixed-width lower-case hexadecimal field.

Parameters
[in]valueValue to print.
[in]digitsField width, 1..k_c6_fwver_hex_digits; an out-of-range width prints nothing rather than overrunning the output array.
Returns
Nothing.
Precondition
The console is up.
digits is within 1..k_c6_fwver_hex_digits.
Postcondition
Exactly digits characters were emitted, or none on a bad width.
No application state is modified.
Note
The loop is bounded by the range-checked digits (NASA Rule 2).
See also
c6_fwver_put_u32
Since
0.1.0

Definition at line 95 of file c6_fwver_console.c.

References k_c6_fwver_hex_alpha, k_c6_fwver_hex_bits, k_c6_fwver_hex_digits, k_c6_fwver_hex_mask, and ra8_board_uart_console_write().

Referenced by c6_fwver_print_reject(), c6_fwver_priv_consume(), c6_fwver_priv_tlv(), c6_fwver_rpc_print_expectation(), and c6_fwver_rpc_print_response().

◆ c6_fwver_put_i32()

void c6_fwver_put_i32 ( int32_t value)

Emit a signed 32-bit value in decimal.

Parameters
[in]valueValue to print, including INT32_MIN.
Returns
Nothing.
Precondition
The console is up.
The caller accepts a leading minus sign on negative values.
Postcondition
One optional sign plus the decimal magnitude were emitted.
No application state is modified.
Note
The magnitude is formed in unsigned arithmetic, so INT32_MIN does not overflow on negation.
See also
c6_fwver_put_u32
Since
0.1.0

Emit a signed 32-bit value in decimal.

Definition at line 85 of file c6_fwver_console.c.

References c6_fwver_put_u32(), and c6_fwver_puts().

Referenced by c6_fwver_rpc_print_response().

◆ c6_fwver_put_text()

void c6_fwver_put_text ( const uint8_t * text,
size_t len )

Emit a length-counted byte range as printable text.

The co-processor supplies the bytes, so nothing about them is trusted: the range is truncated to k_c6_fwver_text_max and every byte outside printable ASCII is replaced with a full stop. A protocol field is evidence, and evidence that can reprogram a terminal is not evidence.

Parameters
[in]textBytes to emit; null prints nothing.
[in]lenNumber of bytes available at text.
Returns
Nothing.
Precondition
The console is up.
len bytes are readable at text.
Postcondition
At most k_c6_fwver_text_max characters were emitted.
No application state is modified.
Note
The loop is bounded by k_c6_fwver_text_max (NASA Rule 2).
See also
c6_fwver_puts
Since
0.1.0

Emit a length-counted byte range as printable text.

Definition at line 112 of file c6_fwver_console.c.

References k_c6_fwver_ascii_high, k_c6_fwver_ascii_low, k_c6_fwver_ascii_sub, k_c6_fwver_text_max, and ra8_board_uart_console_write().

Referenced by c6_fwver_rpc_print_response().

◆ c6_fwver_put_u32()

void c6_fwver_put_u32 ( uint32_t value)

Emit an unsigned 32-bit value in decimal.

Parameters
[in]valueValue to print; the whole 32-bit range is representable.
Returns
Nothing.
Precondition
The console is up.
The caller wants no padding; zero prints as a single digit.
Postcondition
Between one and k_c6_fwver_dec_digits characters were emitted.
No application state is modified.
Note
Not thread-safe, for the same reason as c6_fwver_puts.
See also
c6_fwver_put_i32
Since
0.1.0

Emit an unsigned 32-bit value in decimal.

Definition at line 66 of file c6_fwver_console.c.

References k_c6_fwver_dec_digits, k_c6_fwver_dec_radix, and ra8_board_uart_console_write().

Referenced by c6_fwver_dispatch(), c6_fwver_heartbeat(), c6_fwver_phase_caps(), c6_fwver_phase_request(), c6_fwver_print_banner(), c6_fwver_print_pump(), c6_fwver_print_reject(), c6_fwver_priv_consume(), c6_fwver_priv_tlv(), c6_fwver_put_i32(), c6_fwver_rpc_consume(), c6_fwver_rpc_print_crosscheck(), c6_fwver_rpc_print_expectation(), c6_fwver_rpc_print_response(), and c6_fwver_rpc_report().

◆ c6_fwver_puts()

void c6_fwver_puts ( const char * text)

Write a NUL-terminated string to the board console.

Parameters
[in]textString to emit; null is ignored rather than dereferenced and the length is capped at k_c6_fwver_str_max.
Returns
Nothing.
Precondition
ra8_board_uart_console_init has succeeded.
text is NUL-terminated within k_c6_fwver_str_max bytes.
Postcondition
The bytes are queued on the console transmitter.
No application state is modified.
Note
Not thread-safe; only pre-kernel bring-up and the single worker thread call it, and those never overlap.
See also
c6_fwver_put_u32
Since
0.1.0

Definition at line 53 of file c6_fwver_console.c.

References k_c6_fwver_str_max, and ra8_board_uart_console_write().

Referenced by c6_fwver_dispatch(), c6_fwver_heartbeat(), c6_fwver_phase_caps(), c6_fwver_phase_request(), c6_fwver_print_banner(), c6_fwver_print_pump(), c6_fwver_print_reject(), c6_fwver_priv_consume(), c6_fwver_priv_tlv(), c6_fwver_put_i32(), c6_fwver_rpc_consume(), c6_fwver_rpc_print_crosscheck(), c6_fwver_rpc_print_expectation(), c6_fwver_rpc_print_response(), c6_fwver_rpc_report(), c6_fwver_rx_dispatch(), c6_fwver_worker_entry(), main(), and tx_application_define().

◆ c6_fwver_rpc_consume()

bool c6_fwver_rpc_consume ( uint8_t if_type,
uint8_t if_num,
const uint8_t * payload,
uint16_t len )

Decode an ESP_SERIAL_IF frame as the awaited RPC response.

Unwraps the TLV envelope, unpacks the Rpc message with the vendored codec, and – only when it is the response to this application's request – records every field for the verdict.

Parameters
[in]if_typeInterface type from the received header.
[in]if_numInterface number from the received header.
[in]payloadFrame payload; null is ignored.
[in]lenPayload length in bytes.
Returns
true when the awaited response has been recorded and the pump should stop.
Return values
trueThe response to this request arrived and was decoded.
falseThe frame was something else, or could not be decoded.
Precondition
The console is up.
len bytes are readable at payload.
Postcondition
On true the recorded response is complete and c6_fwver_rpc_report can judge it.
No frame is decoded twice: the first accepted response wins.
Note
Matches c6_fwver_sink_t so the pump can call it directly.
See also
c6_fwver_rpc_report
Since
0.1.0

Definition at line 369 of file c6_fwver_rpc.c.

References c6_fwver_put_u32(), c6_fwver_puts(), c6_fwver_rpc_take(), c6_fwver_tlv_body(), s_c6_fwver_allocator, and s_c6_fwver_rsp.

Referenced by c6_fwver_dispatch().

◆ c6_fwver_rpc_report()

bool c6_fwver_rpc_report ( void )

Print the recorded response and decide the run's verdict.

Prints every decoded field, then the version this host expects, and then exactly one PASS/FAIL line. The expectation is the vendored host driver's own version from esp_hosted_host_fw_ver.h, so the check is the host/co-processor version lock rather than a literal written twice.

Returns
true when the response arrived and every checked field matched.
Return values
trueThe co-processor answered with the expected version.
falseNo response arrived, or a field did not match.
Precondition
The console is up.
A pump has run, so a response either arrived or provably did not.
Postcondition
Exactly one verdict line was emitted.
No application state is modified.
Note
The verdict is printed here rather than returned only, so the console capture that CI greps and the value the code sees cannot disagree.
See also
c6_fwver_rpc_consume
Since
0.1.0

Definition at line 499 of file c6_fwver_rpc.c.

References c6_fwver_put_u32(), c6_fwver_puts(), c6_fwver_rpc_print_crosscheck(), c6_fwver_rpc_print_expectation(), c6_fwver_rpc_print_response(), k_c6_fwver_rpc_uid, and s_c6_fwver_rsp.

Referenced by c6_fwver_worker_entry().

◆ c6_fwver_rpc_request()

ra8_err_t c6_fwver_rpc_request ( uint8_t * out,
uint16_t cap,
uint16_t * out_len )
nodiscard

Build the TLV-wrapped RPC firmware-version request.

Packs an Rpc protobuf message carrying RPC_ID__Req_GetCoprocessorFwVersion with the vendored generated codec, then wraps it in the two-tag TLV envelope the co-processor's serial endpoint expects (endpoint name, then data), exactly as compose_tlv() does in the vendored serial_if.c.

Parameters
[out]outBuffer to fill; must be non-null.
[in]capBytes available at out.
[out]out_lenBytes written; must be non-null.
Returns
ra8_err_t Error code.
Return values
k_ra8_okThe request was built and out_len is its length.
k_ra8_err_null_ptrout or out_len was null.
k_ra8_err_invalid_sizecap cannot hold the envelope.
k_ra8_err_validation_failedThe generated codec packed a different number of bytes than it predicted.
Precondition
cap bytes are writable at out.
The caller transmits the result on ESP_SERIAL_IF, interface 0.
Postcondition
On success out_len is non-zero and at most cap.
On failure out_len is zero.
Note
Pure formatting; touches no hardware and is safe from any thread.
See also
c6_fwver_rpc_consume
Since
0.1.0

Definition at line 217 of file c6_fwver_rpc.c.

References c6_fwver_tlv_head(), k_c6_fwver_rpc_uid, k_c6_fwver_tlv_ep_len, k_c6_fwver_tlv_overhead, k_c6_fwver_tlv_t_data, k_c6_fwver_tlv_t_epname, k_ra8_err_invalid_size, k_ra8_err_null_ptr, k_ra8_err_validation_failed, and k_ra8_ok.

Referenced by c6_fwver_phase_request().