ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
Loading...
Searching...
No Matches
ra8_log.c
Go to the documentation of this file.
1
29
30#include "ra8_log.h"
31
32#include <stdint.h>
33
34#include "ra8_attributes.h"
35#include "ra8_scb.h"
36
37/* =============================================================================
38 * Optional byte sink -- redirect log output off ITM at run time.
39 * =============================================================================
40 */
41
48
54static void* s_byte_sink_ctx = nullptr;
55
57{
58 s_byte_sink = fn;
59 s_byte_sink_ctx = ctx;
60}
61
62/* =============================================================================
63 * ITM stimulus port 0 -- CoreSight ITM (Cortex-M85 has one).
64 * =============================================================================
65 */
66
67typedef enum : uintptr_t {
68 k_ra8_itm_stim_base = 0xE0000000UL,
69 k_ra8_itm_tcr_addr = 0xE0000E80UL,
70 k_ra8_itm_tenr_addr = 0xE0000E00UL,
72
73#ifndef RA8_OFF_TARGET
91RA8_HW_REGISTER_ACCESS RA8_INTERNAL static inline volatile uint32_t* internal_itm_stim0(void)
92{
93 return (volatile uint32_t*)k_ra8_itm_stim_base;
94}
95
113RA8_HW_REGISTER_ACCESS RA8_INTERNAL static inline volatile uint32_t* internal_itm_tcr(void)
114{
115 return (volatile uint32_t*)k_ra8_itm_tcr_addr;
116}
117
135RA8_HW_REGISTER_ACCESS RA8_INTERNAL static inline volatile uint32_t* internal_itm_tenr(void)
136{
137 return (volatile uint32_t*)k_ra8_itm_tenr_addr;
138}
139#endif
140
162RA8_INTERNAL static inline bool internal_itm_ready(void)
163{
164 /* A redirected byte sink needs no ITM/debugger -- it is always ready.
165 * Off target that is the complete readiness condition. On target the
166 * architectural checks still run when no sink is installed. */
167#ifdef RA8_OFF_TARGET
168 return s_byte_sink != nullptr;
169#else
170 if (s_byte_sink != nullptr) {
171 return true;
172 }
173 /* Hardening: if DEMCR.TRCENA is clear the ITM block is powered down
174 * and any read of its registers (TCR, TENR, STIM) will bus-fault.
175 * Pre-check TRCENA via the shared ra8_scb primitive (DEMCR is always
176 * accessible) before touching ITM.
177 *
178 * This was the root cause of escalation-to-LOCKUP observed during
179 * USB bring-up: the original USB fault entered the fault handler,
180 * which called this function, which read ITM_TCR with TRCENA=0 ->
181 * second fault -> LOCKUP at PC=0xEFFFFFFE, hiding the real PC. */
182 if (!ra8_scb_trace_enabled()) {
183 return false;
184 }
185 /* Additional belt-and-braces: never poke ITM from a fault context.
186 * IPSR != 0 means we are inside an exception handler. Even if
187 * TRCENA happens to be on, dropping log lines is preferable to a
188 * second fault that masks the original PC. */
189 volatile uint32_t ipsr = 0U;
190 __asm__ volatile("mrs %0, ipsr" : "=r"(ipsr));
191 if (ipsr != 0U) {
192 return false;
193 }
194 const uint32_t tcr = *internal_itm_tcr();
195 const uint32_t tenr = *internal_itm_tenr();
196 /* TCR bit 0 = ITMENA. TENR bit 0 = stimulus port 0 enabled. */
197 if ((tcr & 1U) == 0U) {
198 return false;
199 }
200 if ((tenr & 1U) == 0U) {
201 return false;
202 }
203 return *internal_itm_stim0() != 0U;
204#endif
205}
206
229RA8_INTERNAL static inline void internal_itm_putc(uint8_t byte)
230{
231 if (s_byte_sink != nullptr) {
233 return;
234 }
235#ifdef RA8_OFF_TARGET
236 /* Hosted builds reach this only with no sink installed, and
237 * `internal_itm_ready()` already reported the backend unavailable in that
238 * case, so every caller has returned before here. Compiling the ITM
239 * fallback out completes commit "keep hosted logging off target MMIO":
240 * the target-only accessors above are already excluded the same way, and
241 * leaving this loop in would be the one remaining host reference to
242 * `k_ra8_itm_stim_base`. */
243 (void)byte;
244#else
245 /* A real build should pre-check `internal_itm_ready()` once during
246 * init and skip the call entirely when the debugger is absent. For
247 * now we poll with a small bound so a disconnected debugger never
248 * stalls the firmware. */
249 enum : uint32_t {
250 k_ra8_itm_poll_limit = 1000U,
251 };
252 for (uint32_t i = 0U; i < k_ra8_itm_poll_limit; i++) {
253 if (*internal_itm_stim0() != 0U) {
254 *(volatile uint8_t*)k_ra8_itm_stim_base = byte;
255 return;
256 }
257 }
258#endif
259}
260
277RA8_INTERNAL static inline void internal_itm_puts(const char* s)
278{
279 while (*s != '\0') {
280 internal_itm_putc((uint8_t)*s++);
281 }
282}
283
304typedef enum : uint8_t {
308
309/* Itm put u32 -- see implementation for details. */
310RA8_INTERNAL static inline void internal_itm_put_u32(uint32_t value)
311{
312 char buf[k_ra8_u32_max_digits + 1U] = {};
313 uint8_t i = 0U;
314 if (value == 0U) {
316 return;
317 }
318 /* mcdc-deactivated: internal_itm_put_u32 digit-buffer watchdog; UINT32_MAX is exactly 10 decimal digits and k_ra8_u32_max_digits == 10, so `value` reaches 0 on or before the tenth iteration and `i < k_ra8_u32_max_digits` is constant-true whenever it is evaluated. */
319 while (value != 0U && i < k_ra8_u32_max_digits) {
320 buf[i++] = (char)('0' + (char)(value % (uint32_t)k_ra8_decimal_base));
321 value /= (uint32_t)k_ra8_decimal_base;
322 }
323 /* Digits were pushed LSB-first; emit MSB-first. */
324 while (i > 0U) {
325 i--;
326 internal_itm_putc((uint8_t)buf[i]);
327 }
328}
329
348RA8_INTERNAL static inline void internal_itm_put_i32(int32_t value)
349{
350 if (value < 0) {
351 internal_itm_putc((uint8_t)'-');
352 /* Casting INT32_MIN negated is UB; subtract through uint32_t. */
353 internal_itm_put_u32((uint32_t)(-(int64_t)value));
354 return;
355 }
356 internal_itm_put_u32((uint32_t)value);
357}
358
359/* =============================================================================
360 * Public API (weak so downstream can override)
361 * =============================================================================
362 */
363
379void ra8_log_init(void)
380{
381 /* ITM is set up by the debugger when it attaches. Nothing to do here
382 * in the default backend. A UART-backed override would configure its
383 * SCI channel in its own ra8_log_init(). */
384}
385
405RA8_INTERNAL static void internal_emit_line(const char* level, const char* tag, const char* msg)
406{
407 if (!internal_itm_ready()) {
408 return;
409 }
410 internal_itm_putc((uint8_t)'[');
412 internal_itm_putc((uint8_t)']');
413 internal_itm_putc((uint8_t)' ');
414 internal_itm_puts(level);
415 internal_itm_putc((uint8_t)':');
416 internal_itm_putc((uint8_t)' ');
418 internal_itm_putc((uint8_t)'\r');
419 internal_itm_putc((uint8_t)'\n');
420}
421
441RA8_INTERNAL static void
442internal_emit_line_u(const char* level, const char* tag, const char* msg, uint32_t value)
443{
444 if (!internal_itm_ready()) {
445 return;
446 }
447 internal_itm_putc((uint8_t)'[');
449 internal_itm_putc((uint8_t)']');
450 internal_itm_putc((uint8_t)' ');
451 internal_itm_puts(level);
452 internal_itm_putc((uint8_t)':');
453 internal_itm_putc((uint8_t)' ');
455 internal_itm_putc((uint8_t)'=');
457 internal_itm_putc((uint8_t)'\r');
458 internal_itm_putc((uint8_t)'\n');
459}
460
480RA8_INTERNAL static void
481internal_emit_line_i(const char* level, const char* tag, const char* msg, int32_t value)
482{
483 if (!internal_itm_ready()) {
484 return;
485 }
486 internal_itm_putc((uint8_t)'[');
488 internal_itm_putc((uint8_t)']');
489 internal_itm_putc((uint8_t)' ');
490 internal_itm_puts(level);
491 internal_itm_putc((uint8_t)':');
492 internal_itm_putc((uint8_t)' ');
494 internal_itm_putc((uint8_t)'=');
496 internal_itm_putc((uint8_t)'\r');
497 internal_itm_putc((uint8_t)'\n');
498}
499
500/* ---- plain string log -------------------------------------------------- */
501
502[[gnu::weak]] void ra8_log_emit_error(const char* tag, const char* message)
503{
504 internal_emit_line("ERROR", tag, message);
505}
506
507[[gnu::weak]] void ra8_log_emit_warn(const char* tag, const char* message)
508{
509 internal_emit_line("WARN", tag, message);
510}
511
512[[gnu::weak]] void ra8_log_emit_info(const char* tag, const char* message)
513{
514 internal_emit_line("INFO", tag, message);
515}
516
517[[gnu::weak]] void ra8_log_emit_debug(const char* tag, const char* message)
518{
519 internal_emit_line("DEBUG", tag, message);
520}
521
522/* ---- string + value log ------------------------------------------------- */
523
538[[gnu::weak]] void ra8_log_emit_error_val(const char* tag, const char* message, uint32_t value)
539{
540 internal_emit_line_u("ERROR", tag, message, value);
541}
542
557[[gnu::weak]] void ra8_log_emit_warn_val(const char* tag, const char* message, uint32_t value)
558{
559 internal_emit_line_u("WARN", tag, message, value);
560}
561
576[[gnu::weak]] void ra8_log_emit_info_val(const char* tag, const char* message, uint32_t value)
577{
578 internal_emit_line_u("INFO", tag, message, value);
579}
580
595[[gnu::weak]] void ra8_log_emit_debug_val(const char* tag, const char* message, int32_t value)
596{
597 internal_emit_line_i("DEBUG", tag, message, value);
598}
599
600/* =============================================================================
601 * ra8_err_to_str (lives here because the log backend is the only user)
602 * =============================================================================
603 */
604
605#include "ra8_err.h"
606
622typedef struct {
624 const char* name;
626
649 {k_ra8_ok, "ok"},
650 {k_ra8_fail, "fail"},
651 {k_ra8_err_no_mem, "no_mem"},
652 {k_ra8_err_invalid_arg, "invalid_arg"},
653 {k_ra8_err_invalid_state, "invalid_state"},
654 {k_ra8_err_invalid_size, "invalid_size"},
655 {k_ra8_err_not_found, "not_found"},
656 {k_ra8_err_not_supported, "not_supported"},
657 {k_ra8_err_timeout, "timeout"},
658 {k_ra8_err_busy, "busy"},
659 {k_ra8_err_no_data, "no_data"},
660 {k_ra8_err_would_block, "would_block"},
661 {k_ra8_err_exists, "exists"},
662 {k_ra8_err_empty, "empty"},
663 {k_ra8_err_cancelled, "cancelled"},
664 {k_ra8_err_not_initialized, "not_initialized"},
665 {k_ra8_err_estop, "estop"},
666 {k_ra8_err_not_empty, "not_empty"},
667 {k_ra8_err_access_denied, "access_denied"},
668 {k_ra8_err_hw_init_failed, "hw_init_failed"},
669 {k_ra8_err_hw_not_ready, "hw_not_ready"},
670 {k_ra8_err_hw_timeout, "hw_timeout"},
671 {k_ra8_err_hw_error, "hw_error"},
672 {k_ra8_err_gpio_conflict, "gpio_conflict"},
673 {k_ra8_err_gpio_invalid_port, "gpio_invalid_port"},
674 {k_ra8_err_gpio_invalid_pin, "gpio_invalid_pin"},
675 {k_ra8_err_out_of_range, "out_of_range"},
676 {k_ra8_err_hw_unmapped, "hw_unmapped"},
677 {k_ra8_err_rtos_error, "rtos_error"},
678 {k_ra8_err_rtos_thread_create, "rtos_thread_create"},
679 {k_ra8_err_rtos_semaphore, "rtos_semaphore"},
680 {k_ra8_err_rtos_mutex, "rtos_mutex"},
681 {k_ra8_err_rtos_queue, "rtos_queue"},
682 {k_ra8_err_rtos_timer, "rtos_timer"},
683 {k_ra8_err_comm_error, "comm_error"},
684 {k_ra8_err_spi_error, "spi_error"},
685 {k_ra8_err_uart_error, "uart_error"},
686 {k_ra8_err_i2c_error, "i2c_error"},
687 {k_ra8_err_crc_mismatch, "crc_mismatch"},
688 {k_ra8_err_protocol_error, "protocol_error"},
689 {k_ra8_err_nack, "nack"},
690 {k_ra8_err_conflict, "conflict"},
691 {k_ra8_err_retry_limit, "retry_limit"},
692 {k_ra8_err_validation_failed, "validation_failed"},
693 {k_ra8_err_checksum_mismatch, "checksum_mismatch"},
694 {k_ra8_err_range_check_failed, "range_check_failed"},
695 {k_ra8_err_null_ptr, "null_ptr"},
696 {k_ra8_err_decomp_output_cap, "decomp_output_cap"},
697 {k_ra8_err_decomp_ratio, "decomp_ratio"},
698 {k_ra8_err_decomp_entries, "decomp_entries"},
699 {k_ra8_err_decomp_depth, "decomp_depth"},
700 {k_ra8_err_decomp_iterations, "decomp_iterations"},
701};
702
712static const uint32_t s_ra8_err_names_count =
713 (uint32_t)(sizeof(s_ra8_err_names) / sizeof(s_ra8_err_names[0]));
714
737const char* ra8_err_to_str(ra8_err_t err)
738{
739 for (uint32_t i = 0; i < s_ra8_err_names_count; i++) {
740 if (s_ra8_err_names[i].code == err) {
741 return s_ra8_err_names[i].name;
742 }
743 }
744 return "unknown";
745}
Annotation-attribute framework macros for ra8-firmware.
#define RA8_HW_REGISTER_ACCESS
Mark an MMIO accessor function (returns volatile register pointer).
#define RA8_INTERNAL
Marker that a function is intended to be static (file-local).
Error Code Definitions for ra8-firmware.
@ k_ra8_err_rtos_mutex
Mutex API error (reserved for future use).
Definition ra8_err.h:375
@ k_ra8_err_retry_limit
Retry budget exhausted – operation still failing after all attempts.
Definition ra8_err.h:447
@ k_ra8_err_hw_init_failed
Hardware peripheral failed to initialise.
Definition ra8_err.h:290
@ k_ra8_err_not_supported
Requested feature not compiled in, not wired, or not supported by this MCU variant.
Definition ra8_err.h:180
@ k_ra8_err_crc_mismatch
CRC mismatch detected on received data.
Definition ra8_err.h:423
@ k_ra8_err_no_mem
Static buffer exhausted (no dynamic memory on this project).
Definition ra8_err.h:142
@ k_ra8_err_empty
Container empty – nothing to retrieve.
Definition ra8_err.h:222
@ k_ra8_err_busy
Resource busy – blocking operation cannot proceed.
Definition ra8_err.h:195
@ k_ra8_err_rtos_thread_create
Thread create failed (reserved for future use).
Definition ra8_err.h:363
@ k_ra8_err_no_data
No application data available (e.g.
Definition ra8_err.h:202
@ k_ra8_err_decomp_ratio
Compression ratio bound breached (ra8_decomp_limits_t).
Definition ra8_err.h:499
@ k_ra8_err_would_block
Non-blocking operation would have blocked.
Definition ra8_err.h:210
@ k_ra8_err_not_empty
Container still holds members – the operation requires it empty.
Definition ra8_err.h:258
@ k_ra8_err_hw_unmapped
Peripheral register block is not mapped in this MCU variant.
Definition ra8_err.h:345
@ k_ra8_err_spi_error
SPI transfer failed (bus fault, mode fault, overrun, ...).
Definition ra8_err.h:405
@ k_ra8_err_checksum_mismatch
Stored / transmitted checksum does not match computed value.
Definition ra8_err.h:465
@ k_ra8_fail
Generic unspecified failure.
Definition ra8_err.h:133
@ k_ra8_err_out_of_range
Sensor or peripheral output out of valid range.
Definition ra8_err.h:337
@ k_ra8_err_invalid_arg
Invalid function argument.
Definition ra8_err.h:152
@ k_ra8_err_exists
Item already exists – cannot create again.
Definition ra8_err.h:216
@ k_ra8_err_invalid_state
Module in wrong state for requested operation.
Definition ra8_err.h:161
@ k_ra8_err_hw_timeout
Hardware timed out waiting for a flag or handshake.
Definition ra8_err.h:304
@ k_ra8_err_validation_failed
Validation rule failed (caller-supplied invariant not satisfied).
Definition ra8_err.h:459
@ k_ra8_err_decomp_output_cap
Decompression output cap breached (ra8_decomp_limits_t).
Definition ra8_err.h:489
@ k_ra8_err_range_check_failed
Value outside range enforced by RA8_CHECK_RANGE / RA8_CHECK_RANGE_TAG.
Definition ra8_err.h:471
@ k_ra8_err_not_initialized
Module not initialized – _init() not yet called successfully.
Definition ra8_err.h:235
@ k_ra8_ok
Success – operation completed with all postconditions satisfied.
Definition ra8_err.h:119
@ k_ra8_err_null_ptr
Pointer was NULL where a valid pointer was required.
Definition ra8_err.h:478
@ k_ra8_err_hw_not_ready
Hardware peripheral exists but not ready yet.
Definition ra8_err.h:298
@ k_ra8_err_rtos_queue
Queue / message API error (reserved for future use).
Definition ra8_err.h:381
@ k_ra8_err_hw_error
Generic hardware fault detected (error flag set, fault interrupt).
Definition ra8_err.h:310
@ k_ra8_err_rtos_error
Generic RTOS error (reserved for future use).
Definition ra8_err.h:357
@ k_ra8_err_gpio_invalid_pin
GPIO pin index out of range within its port (valid: 0..15).
Definition ra8_err.h:331
@ k_ra8_err_estop
Emergency stop active – operation forbidden until cleared.
Definition ra8_err.h:245
@ k_ra8_err_access_denied
Operation refused because the target is protected against it.
Definition ra8_err.h:276
@ k_ra8_err_protocol_error
Protocol-level error (e.g.
Definition ra8_err.h:429
@ k_ra8_err_gpio_conflict
GPIO pin already owned by another peripheral or driver.
Definition ra8_err.h:318
@ k_ra8_err_decomp_iterations
Decode-loop iteration budget exhausted (ra8_decomp_limits_t).
Definition ra8_err.h:531
@ k_ra8_err_uart_error
UART / SCI error (framing, parity, overrun, break).
Definition ra8_err.h:411
@ k_ra8_err_i2c_error
I2C / IIC error (arbitration lost, NACK, timeout, bus error).
Definition ra8_err.h:417
@ k_ra8_err_timeout
Operation exceeded its time budget.
Definition ra8_err.h:188
@ k_ra8_err_not_found
Requested item not found (lookup / search missed).
Definition ra8_err.h:173
@ k_ra8_err_comm_error
Generic communication error (use a more specific code when possible).
Definition ra8_err.h:399
@ k_ra8_err_rtos_timer
Timer API error (reserved for future use).
Definition ra8_err.h:387
@ k_ra8_err_cancelled
Operation cancelled before completion.
Definition ra8_err.h:229
@ k_ra8_err_conflict
Conflict with concurrent access detected.
Definition ra8_err.h:441
@ k_ra8_err_decomp_depth
Container nesting-depth cap breached (ra8_decomp_limits_t).
Definition ra8_err.h:520
@ k_ra8_err_rtos_semaphore
Semaphore API error (reserved for future use).
Definition ra8_err.h:369
@ k_ra8_err_nack
Peer responded with NACK (negative acknowledgement).
Definition ra8_err.h:435
@ k_ra8_err_gpio_invalid_port
GPIO port index out of range for this MCU.
Definition ra8_err.h:325
@ k_ra8_err_invalid_size
Invalid size parameter (too large, too small, or misaligned).
Definition ra8_err.h:167
@ k_ra8_err_decomp_entries
Archive entry-count cap breached (ra8_decomp_limits_t).
Definition ra8_err.h:509
ra8_err_codes_t ra8_err_t
Canonical error-return type used by every ra8-firmware API.
Definition ra8_err.h:546
static volatile uint32_t * internal_itm_tenr(void)
Get the ITM Trace Enable Register.
Definition ra8_log.c:135
static void * s_byte_sink_ctx
Opaque cookie passed back to s_byte_sink on every byte.
Definition ra8_log.c:54
static void internal_itm_puts(const char *s)
Emit a NUL-terminated string over ITM port 0.
Definition ra8_log.c:277
ra8_log_u32_t
Emit an unsigned decimal integer over ITM port 0.
Definition ra8_log.c:304
@ k_ra8_decimal_base
Decimal radix.
Definition ra8_log.c:306
@ k_ra8_u32_max_digits
Max decimal digits in a uint32_t.
Definition ra8_log.c:305
static bool internal_itm_ready(void)
Check whether ITM port 0 is enabled and ready to accept bytes.
Definition ra8_log.c:162
void ra8_log_init(void)
Default log backend init – no-op for the ITM sink.
Definition ra8_log.c:379
static const ra8_err_name_entry_t s_ra8_err_names[]
Lookup table backing ra8_err_to_str().
Definition ra8_log.c:648
void ra8_log_set_byte_sink(ra8_log_byte_sink_fn_t fn, void *ctx)
Install (or clear) an optional byte sink for log output.
Definition ra8_log.c:56
void ra8_log_emit_info(const char *tag, const char *message)
Emit an INFO-level log line with only a tag and a message.
Definition ra8_log.c:512
static void internal_emit_line(const char *level, const char *tag, const char *msg)
Common tagged-line emit helper.
Definition ra8_log.c:405
void ra8_log_emit_error(const char *tag, const char *message)
Emit an ERROR-level log line with only a tag and a message.
Definition ra8_log.c:502
static void internal_emit_line_i(const char *level, const char *tag, const char *msg, int32_t value)
Common tagged-line-with-value emit helper (signed).
Definition ra8_log.c:481
static volatile uint32_t * internal_itm_tcr(void)
Get the ITM Trace Control Register.
Definition ra8_log.c:113
void ra8_log_emit_debug(const char *tag, const char *message)
Emit a DEBUG-level log line with only a tag and a message.
Definition ra8_log.c:517
static void internal_itm_putc(uint8_t byte)
Blocking-but-bounded write of a single byte to ITM port 0.
Definition ra8_log.c:229
static void internal_itm_put_i32(int32_t value)
Emit a signed decimal integer over ITM port 0.
Definition ra8_log.c:348
static volatile uint32_t * internal_itm_stim0(void)
Get the ITM stimulus-port-0 register.
Definition ra8_log.c:91
void ra8_log_emit_info_val(const char *tag, const char *message, uint32_t value)
INFO-level log emitter that also reports a uint32 value.
Definition ra8_log.c:576
void ra8_log_emit_warn_val(const char *tag, const char *message, uint32_t value)
WARN-level log emitter that also reports a uint32 value.
Definition ra8_log.c:557
static ra8_log_byte_sink_fn_t s_byte_sink
Active log byte sink, or nullptr to use the default ITM port.
Definition ra8_log.c:47
ra8_itm_addr_t
Definition ra8_log.c:67
@ k_ra8_itm_stim_base
ITM stimulus port 0 base.
Definition ra8_log.c:68
@ k_ra8_itm_tcr_addr
ITM Trace Control Register.
Definition ra8_log.c:69
@ k_ra8_itm_tenr_addr
ITM Trace Enable Register.
Definition ra8_log.c:70
void ra8_log_emit_debug_val(const char *tag, const char *message, int32_t value)
DEBUG-level log emitter that also reports a signed int32 value.
Definition ra8_log.c:595
void ra8_log_emit_error_val(const char *tag, const char *message, uint32_t value)
ERROR-level log emitter that also reports a uint32 value.
Definition ra8_log.c:538
static void internal_itm_put_u32(uint32_t value)
Definition ra8_log.c:310
const char * ra8_err_to_str(ra8_err_t err)
Implementation of ra8_err_to_str() – linear-scan lookup.
Definition ra8_log.c:737
static void internal_emit_line_u(const char *level, const char *tag, const char *msg, uint32_t value)
Common tagged-line-with-value emit helper (unsigned).
Definition ra8_log.c:442
void ra8_log_emit_warn(const char *tag, const char *message)
Emit a WARN-level log line with only a tag and a message.
Definition ra8_log.c:507
static const uint32_t s_ra8_err_names_count
Number of entries in s_ra8_err_names.
Definition ra8_log.c:712
Lightweight Logging Interface for ra8-firmware.
void(* ra8_log_byte_sink_fn_t)(void *ctx, uint8_t byte)
Optional per-byte sink for redirecting log output off ITM.
Definition ra8_log.h:144
Cortex-M85 System Control Block: VTOR relocation + fault-status decode.
bool ra8_scb_trace_enabled(void)
Report whether DEMCR.TRCENA (trace subsystem enable) is set.
Definition ra8_scb.c:124
Single (code, name) pair in the ra8_err_to_str() lookup table.
Definition ra8_log.c:622
const char * name
Short ASCII name for the code (no spaces).
Definition ra8_log.c:624
ra8_err_t code
Error code value from ra8_err_t.
Definition ra8_log.c:623