ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
Loading...
Searching...
No Matches
main.c
Go to the documentation of this file.
1
64
65#include <stdint.h>
66
67#include "ra8_board_ek_ra8d2.h"
68#include "ra8_boot_entry.h"
69#include "ra8_cgc.h"
70#include "ra8_err.h"
71#include "ra8_isr.h"
72#include "ra8_time.h"
73
74#ifndef RA8_OFF_TARGET
75#include "tx_api.h"
76#endif
77
78/* ---------------------------------------------------------------------------
79 * Demo tunables (typed enums per the no-magic-number rule).
80 * --------------------------------------------------------------------------- */
81
102
111typedef enum : uint32_t {
115
117static const uint8_t k_ipc_demo_banner[] = "[ipc_demo] M85 starting\r\n";
118static const uint8_t k_ipc_demo_send_msg[] = "[ipc_demo] -> ping\r\n";
119static const uint8_t k_ipc_demo_recv_msg[] = "[ipc_demo] <- pong\r\n";
120
133volatile uint32_t g_ipc_demo_tick = 0U;
134
135/* ---------------------------------------------------------------------------
136 * SCI8 helpers.
137 * --------------------------------------------------------------------------- */
138
147static void ipc_demo_panic_halt(void)
148{
149 while (1) {
150 __asm__ volatile("wfi");
151 }
152}
153
167static void ipc_demo_log(const uint8_t* s, uint32_t len)
168{
169 (void)ra8_board_uart_console_write(s, (size_t)len);
170}
171
172/* ---------------------------------------------------------------------------
173 * Boot path: CGC -> pins -> SCI8.
174 * --------------------------------------------------------------------------- */
175
195static void ipc_demo_setup_or_halt(void)
196{
197 uint32_t cpuclk0_hz = 0U;
198
199 if (ra8_cgc_init() != k_ra8_ok) {
201 }
204 }
205 if (ra8_time_init(cpuclk0_hz) != k_ra8_ok) {
207 }
210 }
211}
212
213/* ---------------------------------------------------------------------------
214 * ThreadX bring-up.
215 * --------------------------------------------------------------------------- */
216
217#ifndef RA8_OFF_TARGET
218/* SysTick handler lives in libs/ra8_core/src/ra8_time.c -- the project's
219 * shared weak SysTick_Handler dispatches to ThreadX (via a weak extern
220 * to `_tx_timer_interrupt`) so no per-app override is needed. */
221
232static TX_QUEUE s_ipc_queue;
234
237[[gnu::aligned(8)]] static uint8_t s_producer_stack[k_ipc_demo_thread_stack];
238
241[[gnu::aligned(8)]] static uint8_t s_consumer_stack[k_ipc_demo_thread_stack];
242
262static void ipc_producer_thread_entry(ULONG thread_input)
263{
264 (void)thread_input;
265
266 ipc_demo_log(k_ipc_demo_banner, (uint32_t)(sizeof(k_ipc_demo_banner) - 1U));
267
268 while (1) {
270 /* ``tx_queue_send`` arguments: queue ptr, ptr-to-source (NOT the
271 * value), wait option. The source pointer is read for exactly
272 * ``message_size`` ULONGs as declared at create time. */
273 if (tx_queue_send(&s_ipc_queue, &msg, TX_WAIT_FOREVER) == TX_SUCCESS) {
274 ipc_demo_log(k_ipc_demo_send_msg, (uint32_t)(sizeof(k_ipc_demo_send_msg) - 1U));
275 }
277 }
278}
279
306static void ipc_consumer_thread_entry(ULONG thread_input)
307{
308 (void)thread_input;
309
310 while (1) {
311 ULONG msg = 0U;
312 if (tx_queue_receive(&s_ipc_queue, &msg, TX_WAIT_FOREVER) != TX_SUCCESS) {
313 /* Should not happen with TX_WAIT_FOREVER on a healthy queue,
314 * but if it does we skip the log so the HIL negative-regex
315 * does not trip on spurious output. */
316 continue;
317 }
318 if (msg != (ULONG)k_ipc_demo_payload_ping) {
319 continue;
320 }
321 ipc_demo_log(k_ipc_demo_recv_msg, (uint32_t)(sizeof(k_ipc_demo_recv_msg) - 1U));
322 g_ipc_demo_tick += 1U;
323 }
324}
325
337void tx_application_define(void* first_unused_memory)
338{
339 (void)first_unused_memory;
340
341 /* ThreadX takes non-const CHAR* for object names; use writable static
342 * buffers to avoid -Wdiscarded-qualifiers / -Wcast-qual. */
343 static CHAR s_queue_name[] = "ipc_demo_q";
344 static CHAR s_producer_name[] = "producer";
345 static CHAR s_consumer_name[] = "consumer";
346
347 /* tx_queue_create: message_size is in 32-bit ULONGs (TX_1_ULONG=1),
348 * queue_size is the total backing-buffer byte count. Deriving the
349 * byte count from sizeof() of the same backing array keeps the two
350 * arguments in sync. */
351 if (tx_queue_create(&s_ipc_queue,
352 s_queue_name,
353 TX_1_ULONG,
355 (ULONG)sizeof(s_ipc_queue_storage)) != TX_SUCCESS) {
357 }
358
359 /* Consumer goes first so it is parked in tx_queue_receive before the
360 * producer's first send -- avoids a transient queue-not-empty
361 * window where the consumer would have to sleep to catch up. */
363 s_consumer_name,
365 0U,
373 }
374
376 s_producer_name,
378 0U,
386 }
387}
388#endif /* !RA8_OFF_TARGET */
389
390/* ---------------------------------------------------------------------------
391 * main()
392 * --------------------------------------------------------------------------- */
393
405void main(void)
406{
408
410
411#ifndef RA8_OFF_TARGET
412 tx_kernel_enter();
413#endif
414
416}
void main(void)
Secure fallback main entry point.
Definition main.c:37
void tx_application_define(void *first_unused_memory)
ThreadX system-define hook: build worker thread + byte pool.
Definition main.c:942
static void ipc_demo_panic_halt(void)
Halt forever in WFI on a fatal init failure.
Definition main.c:147
static uint8_t s_producer_stack[k_ipc_demo_thread_stack]
Definition main.c:237
static void ipc_consumer_thread_entry(ULONG thread_input)
Consumer thread body – blocking receive + log.
Definition main.c:306
static uint8_t s_consumer_stack[k_ipc_demo_thread_stack]
Definition main.c:241
static TX_QUEUE s_ipc_queue
ThreadX queue control block + backing storage.
Definition main.c:232
static TX_THREAD s_consumer_thread
ThreadX control block + stack for the consumer thread.
Definition main.c:240
static void ipc_demo_log(const uint8_t *s, uint32_t len)
Write a static ASCII string to SCI8.
Definition main.c:167
static const uint8_t k_ipc_demo_recv_msg[]
Definition main.c:119
static ULONG s_ipc_queue_storage[k_ipc_demo_queue_capacity]
Definition main.c:233
ipc_demo_payload_t
32-bit ASCII payload tags exchanged across the queue.
Definition main.c:111
@ k_ipc_demo_payload_ping
"ping" little-endian.
Definition main.c:112
@ k_ipc_demo_payload_pong
"pong" little-endian.
Definition main.c:113
static void ipc_demo_setup_or_halt(void)
Bring CGC + SCI8 up.
Definition main.c:195
volatile uint32_t g_ipc_demo_tick
HIL liveness counter – incremented per consumer wakeup.
Definition main.c:133
ipc_demo_cfg_t
Compile-time configuration for the ThreadX IPC demo.
Definition main.c:93
@ k_ipc_demo_period_ms
Ipc demo period ms.
Definition main.c:95
@ k_ipc_demo_thread_stack
Ipc demo thread stack.
Definition main.c:97
@ k_ipc_demo_producer_prio
Ipc demo producer prio.
Definition main.c:98
@ k_ipc_demo_period_ticks
1000 ticks @ 1 kHz SysTick = 1 s.
Definition main.c:96
@ k_ipc_demo_queue_capacity
Slots in the inter-thread queue.
Definition main.c:100
@ k_ipc_demo_baud
Ipc demo baud.
Definition main.c:94
@ k_ipc_demo_consumer_prio
Higher prio -> blocks on receive.
Definition main.c:99
static const uint8_t k_ipc_demo_banner[]
Static log lines streamed over SCI8 (must remain ASCII).
Definition main.c:117
static void ipc_producer_thread_entry(ULONG thread_input)
Producer thread body – 1 Hz "ping" enqueue.
Definition main.c:262
static TX_THREAD s_producer_thread
ThreadX control block + stack for the producer thread.
Definition main.c:236
static const uint8_t k_ipc_demo_send_msg[]
Definition main.c:118
Board-support layer for the Renesas EK-RA8D2 v1 evaluation kit.
ra8_err_t ra8_board_uart_console_write(const uint8_t *data, size_t len)
Polled blocking write to the J-Link OB VCOM console.
ra8_err_t ra8_board_uart_console_init(uint32_t baud)
Configure SCI8 + PD02/PD03 as the debug-console UART.
Boot entry points shared between a vector table and its startup code.
High-level Clock Generation Circuit driver.
ra8_err_t ra8_cgc_get_clock_hz(ra8_clock_id_t id, uint32_t *out_hz)
Query the current frequency of a clock-tree domain.
Definition ra8_cgc.c:132
@ k_ra8_clock_id_cpuclk0
Cortex-M85 CPUCLK0.
Definition ra8_cgc.h:70
ra8_err_t ra8_cgc_init(void)
Configure the clock tree to a safe default.
Definition ra8_cgc.c:727
Error Code Definitions for ra8-firmware.
@ k_ra8_ok
Success – operation completed with all postconditions satisfied.
Definition ra8_err.h:119
NVIC + ICU IELSR allocator.
void ra8_isr_globals_enable(void)
Globally enable maskable interrupts (PRIMASK = 0).
Definition ra8_isr.c:439
SysTick-based tick counter, delay and timestamp helpers.
ra8_err_t ra8_time_init(uint32_t cpu_hz)
Initialise SysTick for a 1 kHz tick interrupt.
Definition ra8_time.c:59
unsigned int UINT
ThreadX-compatible unsigned int (host stub).
#define TX_SUCCESS
#define tx_thread_create
#define tx_thread_sleep
#define TX_NO_TIME_SLICE
char CHAR
ThreadX-compatible CHAR (host stub).
#define TX_AUTO_START
#define TX_WAIT_FOREVER
unsigned long ULONG
ThreadX-compatible unsigned long (host stub).
Opaque thread stand-in for the host build.