ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
Loading...
Searching...
No Matches
board_console.c
Go to the documentation of this file.
1
17
18#include "board_console.h"
19
20#include <stdint.h>
21
22#include "ra8_attributes.h"
23
35typedef struct {
38 uint32_t head;
39 uint32_t count;
40 uint32_t total;
42
45
47static const char* const s_k_channel_names[k_board_console_ch_count] = {
48 "ALL",
49 "UART",
50 "ITM",
51 "RTT",
52 "SPI",
53 "I2C",
54 "CAN",
55 "USB",
56 "SD",
57 "OSPI",
58 "I2S",
59 "ADC",
60 "DAC",
61 "GPIO",
62 "DMA",
63 "NET",
64};
65
67{
68 if ((uint32_t)ch >= (uint32_t)k_board_console_ch_count) {
69 return "?";
70 }
71 return s_k_channel_names[(uint32_t)ch];
72}
73
91RA8_INTERNAL static void internal_slot_copy(char* dst, const char* src)
92{
93 if (dst == nullptr) {
94 return;
95 }
96 uint32_t i = 0U;
97 for (; i < (uint32_t)(k_board_console_line_cap - 1U); i++) {
98 if (src == nullptr) {
99 break;
100 }
101 if (src[i] == '\0') {
102 break;
103 }
104 dst[i] = src[i];
105 }
106 dst[i] = '\0';
107}
108
125RA8_INTERNAL static void internal_ring_push(console_ring_t* ring, const char* line)
126{
127 if (ring == nullptr) {
128 return;
129 }
130 if (ring->head >= (uint32_t)k_board_console_ring_depth) {
131 ring->head = 0U; /* defensive: keep the slot index in range */
132 }
133 internal_slot_copy(ring->lines[ring->head], line);
134 ring->head = (ring->head + 1U) % (uint32_t)k_board_console_ring_depth;
135 if (ring->count < (uint32_t)k_board_console_ring_depth) {
136 ring->count++;
137 }
138 ring->total++;
139}
140
158RA8_INTERNAL static void
159internal_format_all_line(board_console_ch_t ch, const char* line, char* out)
160{
161 if (out == nullptr) {
162 return;
163 }
164 const char* name = board_console_name(ch);
165 uint32_t n = 0U;
166 for (; n < (uint32_t)(k_board_console_line_cap - 1U); n++) {
167 if (name[n] == '\0') {
168 break;
169 }
170 out[n] = name[n];
171 }
172 if (n < (uint32_t)(k_board_console_line_cap - 1U)) {
173 out[n] = ' ';
174 n++;
175 }
176 uint32_t j = 0U;
177 for (; n < (uint32_t)(k_board_console_line_cap - 1U); n++) {
178 if (line == nullptr) {
179 break;
180 }
181 if (line[j] == '\0') {
182 break;
183 }
184 out[n] = line[j];
185 j++;
186 }
187 out[n] = '\0';
188}
189
190void board_console_push(board_console_ch_t ch, const char* line)
191{
192 if ((uint32_t)ch == (uint32_t)k_board_console_ch_all) {
193 return; /* ALL is a mirror only; never pushed to directly. */
194 }
195 if ((uint32_t)ch >= (uint32_t)k_board_console_ch_count) {
196 return;
197 }
198 if (line == nullptr) {
199 return;
200 }
201 internal_ring_push(&s_rings[(uint32_t)ch], line);
202 char all_line[k_board_console_line_cap];
203 internal_format_all_line(ch, line, all_line);
205}
206
208{
209 if ((uint32_t)ch >= (uint32_t)k_board_console_ch_count) {
210 return 0U;
211 }
212 return s_rings[(uint32_t)ch].count;
213}
214
216{
217 if ((uint32_t)ch >= (uint32_t)k_board_console_ch_count) {
218 return 0U;
219 }
220 return s_rings[(uint32_t)ch].total;
221}
222
223const char* board_console_line(board_console_ch_t ch, uint32_t back)
224{
225 if ((uint32_t)ch >= (uint32_t)k_board_console_ch_count) {
226 return nullptr;
227 }
228 const console_ring_t* ring = &s_rings[(uint32_t)ch];
229 if (back >= ring->count) {
230 return nullptr; /* older than the retained history */
231 }
232 /* back = 0 is the newest line; head points one past the newest. */
233 const uint32_t idx = (ring->head + (uint32_t)k_board_console_ring_depth - 1U - back) %
235 return ring->lines[idx];
236}
237
239{
240 for (uint32_t ch = 0U; ch < (uint32_t)k_board_console_ch_count; ch++) {
241 s_rings[ch].head = 0U;
242 s_rings[ch].count = 0U;
243 s_rings[ch].total = 0U;
244 }
245}
static const char *const s_k_channel_names[k_board_console_ch_count]
Tab captions, indexed by board_console_ch_t (also the ALL prefix).
static void internal_format_all_line(board_console_ch_t ch, const char *line, char *out)
Build the "<NAME> <line>" form an ALL-ring entry stores.
const char * board_console_line(board_console_ch_t ch, uint32_t back)
Fetch a retained line by age (0 = newest) from a channel.
static console_ring_t s_rings[k_board_console_ch_count]
One ring per channel, including the aggregate ALL ring at index 0.
uint32_t board_console_count(board_console_ch_t ch)
Count of lines currently retained in a channel ring.
void board_console_reset(void)
Clear every channel ring (called on a warm reboot).
const char * board_console_name(board_console_ch_t ch)
Short display name for a channel (the tab caption).
void board_console_push(board_console_ch_t ch, const char *line)
Append one completed line to a channel ring and the ALL ring.
static void internal_slot_copy(char *dst, const char *src)
Copy a bounded, NUL-terminated string into a ring slot.
static void internal_ring_push(console_ring_t *ring, const char *line)
Append one already-formed line to a single ring.
uint32_t board_console_total(board_console_ch_t ch)
Monotonic count of lines ever pushed to a channel.
Multi-channel console log store backing the board view's tabbed console.
@ k_board_console_line_cap
Max chars stored per line (with NUL).
@ k_board_console_ring_depth
Recent lines retained per channel.
board_console_ch_t
Console channels the board view exposes as tabs.
@ k_board_console_ch_all
Aggregate of all lanes (arrival order).
@ k_board_console_ch_count
Channel count (ring + tab array size).
Annotation-attribute framework macros for ra8-firmware.
#define RA8_INTERNAL
Marker that a function is intended to be static (file-local).
One channel's scrollback ring.
uint32_t head
Next write slot (one past newest).
char lines[k_board_console_ring_depth][k_board_console_line_cap]
Row storage.
uint32_t total
Rows ever pushed (monotonic).
uint32_t count
Rows held (saturates at ring depth).