|
ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
|
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"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. | |
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. | |
Shared contract for the esp-hosted RPC round-trip application.
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:
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.
Definition in file c6_fwver.h.
| 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.
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).
| [in] | if_type | Interface type from the received payload header. |
| [in] | if_num | Interface number from the received payload header. |
| [in] | payload | Frame payload; never null, never zero length. |
| [in] | len | Payload length in bytes, at most MAX_PAYLOAD_SIZE. |
Definition at line 237 of file c6_fwver.h.
| 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.
Definition at line 70 of file c6_fwver.h.
| 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.
Definition at line 103 of file c6_fwver.h.
| 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.
Definition at line 138 of file c6_fwver.h.
| 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.
| [in] | if_type | Interface type from the received header. |
| [in] | if_num | Interface number from the received header. |
| [in] | payload | Frame payload; null is ignored. |
| [in] | len | Payload length in bytes. |
| true | The RPC layer accepted the awaited response. |
| false | Everything else, including announcements. |
len bytes are readable at payload. 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().
|
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.
| [in] | if_type | Interface type for the transmitted payload, from esp_hosted_if_type_t. Ignored when payload_len is zero. |
| [in] | if_num | Interface number for the transmitted payload, 0..15. |
| [in] | payload | Payload to transmit once, or null to pump filler only. |
| [in] | payload_len | Length of payload in bytes; must be zero when payload is null and at most k_c6_fwver_tx_max otherwise. |
| [in] | max_transfers | Transactions this call may clock; must be non-zero. |
| [in] | sink | Receiver for well-formed frames, or null to count only. |
| [out] | stats | Counters describing the run; must be non-null. |
| k_ra8_ok | The pump ran; stats says what happened. |
| k_ra8_err_null_ptr | stats was null, or payload_len was non-zero with a null payload. |
| k_ra8_err_invalid_arg | payload_len exceeds k_c6_fwver_tx_max, or max_transfers was zero. |
| k_ra8_err_not_initialized | The esp-hosted port is not up, so the vtable behind g_h cannot be called. |
| k_ra8_err_hw_timeout | HANDSHAKE never went active, so not one transaction was clocked. |
| k_ra8_err_spi_error | A bus transfer did not return RET_OK. |
max_transfers transactions were clocked. stats holds the counts for exactly this call.max_transfers and the HANDSHAKE wait by k_c6_fwver_hs_wait_ms.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().
| void c6_fwver_print_banner | ( | uint32_t | cpuclk_hz, |
| uint32_t | pclka_hz ) |
Print the banner: identity, clocks and SPI parameters.
| [in] | cpuclk_hz | Live CPUCLK0 rate in hertz. |
| [in] | pclka_hz | Live PCLKA rate in hertz, the SCI baud-clock source. |
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().
| void c6_fwver_print_pump | ( | const char * | label, |
| const c6_fwver_pump_stats_t * | stats ) |
Print what one pump did, as one console line.
| [in] | label | Field name printed before the counters; null prints nothing at all rather than being dereferenced. |
| [in] | stats | Counters filled in by c6_fwver_link_pump; null prints nothing. |
stats came from a completed pump. 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().
| 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.
| [in] | if_type | Interface type from the received header. |
| [in] | if_num | Interface number from the received header. |
| [in] | payload | Frame payload; null is ignored. |
| [in] | len | Payload length in bytes. |
| false | The frame was decoded, ignored, or was not a priv frame. |
len bytes are readable at payload. 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().
|
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.
| [out] | out | Buffer to fill; must be non-null. |
| [in] | cap | Bytes available at out. |
| [out] | out_len | Bytes written; must be non-null. |
| k_ra8_ok | The frame was built and out_len is its length. |
| k_ra8_err_null_ptr | out or out_len was null. |
| k_ra8_err_invalid_size | cap cannot hold the frame. |
cap bytes are writable at out. out_len is non-zero and at most cap. out is not modified. 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().
|
nodiscard |
Report the version the boot INIT event announced, if one arrived.
| 0 | No ESP_PRIV_FIRMWARE_VERSION tag has been seen. |
Definition at line 263 of file c6_fwver_priv.c.
References s_c6_fwver_priv_version.
Referenced by c6_fwver_rpc_print_crosscheck().
| void c6_fwver_put_hex | ( | uint32_t | value, |
| uint8_t | digits ) |
Emit a value as a fixed-width lower-case hexadecimal field.
| [in] | value | Value to print. |
| [in] | digits | Field width, 1..k_c6_fwver_hex_digits; an out-of-range width prints nothing rather than overrunning the output array. |
digits is within 1..k_c6_fwver_hex_digits. digits characters were emitted, or none on a bad width. digits (NASA Rule 2). 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().
| void c6_fwver_put_i32 | ( | int32_t | value | ) |
Emit a signed 32-bit value in decimal.
| [in] | value | Value to print, including INT32_MIN. |
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().
| 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.
| [in] | text | Bytes to emit; null prints nothing. |
| [in] | len | Number of bytes available at text. |
len bytes are readable at text. 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().
| void c6_fwver_put_u32 | ( | uint32_t | value | ) |
Emit an unsigned 32-bit value in decimal.
| [in] | value | Value to print; the whole 32-bit range is representable. |
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().
| void c6_fwver_puts | ( | const char * | text | ) |
Write a NUL-terminated string to the board console.
| [in] | text | String to emit; null is ignored rather than dereferenced and the length is capped at k_c6_fwver_str_max. |
text is NUL-terminated within k_c6_fwver_str_max bytes. 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().
| 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.
| [in] | if_type | Interface type from the received header. |
| [in] | if_num | Interface number from the received header. |
| [in] | payload | Frame payload; null is ignored. |
| [in] | len | Payload length in bytes. |
| true | The response to this request arrived and was decoded. |
| false | The frame was something else, or could not be decoded. |
len bytes are readable at payload. 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().
| 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.
| true | The co-processor answered with the expected version. |
| false | No response arrived, or a field did not match. |
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().
|
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.
| [out] | out | Buffer to fill; must be non-null. |
| [in] | cap | Bytes available at out. |
| [out] | out_len | Bytes written; must be non-null. |
| k_ra8_ok | The request was built and out_len is its length. |
| k_ra8_err_null_ptr | out or out_len was null. |
| k_ra8_err_invalid_size | cap cannot hold the envelope. |
| k_ra8_err_validation_failed | The generated codec packed a different number of bytes than it predicted. |
cap bytes are writable at out. out_len is non-zero and at most cap. out_len is zero. 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().