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

Inter-Processor Communication (IPC) HAL driver – sync API. More...

#include <stdint.h>
#include "ra8_attributes.h"
#include "ra8_err.h"
#include "ra8_ipc_regs.h"
#include "ra8_ipc_types.h"
Include dependency graph for ra8_ipc_sync.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

static void ra8_ipc_barrier (void)
 Cross-core data-memory barrier for IPC publish + lock ordering.
ra8_err_t ra8_ipc_sem_try_take (uint8_t sem_id)
 Test-and-set acquire on one IPC hardware semaphore.
ra8_err_t ra8_ipc_sem_take_timeout (uint8_t sem_id, uint16_t max_spins)
 Bounded-spin take on one IPC hardware semaphore.
ra8_err_t ra8_ipc_sem_release (uint8_t sem_id)
 Release one IPC hardware semaphore.
ra8_err_t ra8_ipc_sem_is_locked (uint8_t sem_id, bool *out_locked)
 Predicate: is the semaphore currently locked?
ra8_err_t ra8_ipc_nmi_send (uint8_t unit)
 Issue an inter-processor NMI to the peer core.
ra8_err_t ra8_ipc_nmi_clear (uint8_t unit)
 Acknowledge an inter-processor NMI on the local core.
ra8_err_t ra8_ipc_nmi_get_status (uint8_t unit, bool *out_pending)
 Read NMISTA.NMI for one IPC NMI unit.
ra8_err_t ra8_ipc_attach_nmi_handler (ra8_ipc_nmi_fn_t fn, void *ctx)
 Attach a callback for inter-processor NMI dispatch.
void ra8_ipc_dispatch_nmi (uint8_t unit)
 Drive the NMI dispatch path for one unit.
ra8_err_t ra8_ipc_attach_handler (ra8_ipc_event_fn_t fn, void *ctx)
 Attach a single event callback shared across all channels.
ra8_err_t ra8_ipc_attach_event_handler (uint8_t channel, ra8_ipc_irq_event_id_t event_id, ra8_ipc_irq_fn_t fn, void *ctx)
 Attach a callback for a single IRQ event line on a channel.
void ra8_ipc_dispatch (uint8_t channel)
 Drive the event callback for one channel.
ra8_err_t ra8_ipc_install_isr (uint8_t unit, uint8_t priority)
 Wire the IPC IRQ event into the ISR table.
ra8_err_t ra8_ipc_uninstall_isr (uint8_t unit)
 Tear down a previously installed IPC ISR.
ra8_err_t ra8_ipc_ring_init (ra8_ipc_ring_t *ring)
 Initialise a producer/consumer ring backed by shared SRAM.
ra8_err_t ra8_ipc_ring_produce (ra8_ipc_ring_t *ring, uint32_t payload)
 Push one word into the shared-memory ring (producer side).
ra8_err_t ra8_ipc_ring_consume (ra8_ipc_ring_t *ring, uint32_t *out_payload)
 Pop one word from the shared-memory ring (consumer side).
ra8_err_t ra8_ipc_ring_is_empty (const ra8_ipc_ring_t *ring, bool *out_empty)
 Predicate: ring empty?
ra8_err_t ra8_ipc_ring_is_full (const ra8_ipc_ring_t *ring, bool *out_full)
 Predicate: ring full?

Detailed Description

Inter-Processor Communication (IPC) HAL driver – sync API.

Tag
[Ring 3 / HAL] {World: NS}

Hardware-semaphore, NMI-surface, maskable-interrupt dispatch, and shared-memory ring-buffer protocol prototypes for the RA8D2 IPC mailbox driver. Split out of ra8_ipc.h so each header stays within the repository file-size budget; ra8_ipc.h re-includes this header so existing consumers are unaffected.

Since
0.1.0

Definition in file ra8_ipc_sync.h.

Function Documentation

◆ ra8_ipc_attach_event_handler()

ra8_err_t ra8_ipc_attach_event_handler ( uint8_t channel,
ra8_ipc_irq_event_id_t event_id,
ra8_ipc_irq_fn_t fn,
void * ctx )
nodiscard

Attach a callback for a single IRQ event line on a channel.

Each FIFO channel exposes 8 maskable IRQ event lines (HUM Ch 3.2.10 p 214). This API lets each line have its own decoded callback so application code does not have to walk the bitmask returned by ra8_ipc_dispatch.

Parameters
[in]channelChannel id 0..3.
[in]event_idIRQ event line 0..7.
[in]fnCallback fired when this line is observed in STA. NULL detaches.
[in]ctxOpaque context handed to fn.
Returns
ra8_err_t error code.
Return values
k_ra8_okStored.
k_ra8_err_invalid_argchannel >= 4 or event_id > 7.
Precondition
Channel was initialized.
IRQs masked at install time.
Postcondition
Subsequent ra8_ipc_dispatch invocations call fn(ctx, ch, ev) when STA.IRQev is set in the dispatched mask.
Previous handler for the line is no longer called.
Note
Thread safety: not thread-safe (per-line single slot).
See also
ra8_ipc_dispatch
Since
0.1.0

Definition at line 716 of file ra8_ipc.c.

References ra8_ipc_irq_slot_t::ctx, ra8_ipc_irq_slot_t::fn, k_ra8_err_invalid_arg, k_ra8_ipc_channel_count, k_ra8_ipc_irq_event_count, k_ra8_ok, and s_ipc_channels.

Referenced by arm_ipc_wake().

◆ ra8_ipc_attach_handler()

ra8_err_t ra8_ipc_attach_handler ( ra8_ipc_event_fn_t fn,
void * ctx )
nodiscard

Attach a single event callback shared across all channels.

Parameters
[in]fnCallback fired during dispatch. NULL to detach.
[in]ctxOpaque context forwarded to fn.
Returns
ra8_err_t error code.
Return values
k_ra8_okAlways succeeds.
Precondition
Caller has not registered another callback expecting different semantics (single-slot table).
IRQs are masked or this is single-threaded init.
Postcondition
ra8_ipc_dispatch fires fn with ctx.
The previous callback, if any, is no longer called.
Note
Thread safety: not thread-safe (single-slot global).
See also
ra8_ipc_dispatch
Since
0.1.0

Definition at line 709 of file ra8_ipc.c.

References k_ra8_ok, s_ipc_callback, and s_ipc_context.

◆ ra8_ipc_attach_nmi_handler()

ra8_err_t ra8_ipc_attach_nmi_handler ( ra8_ipc_nmi_fn_t fn,
void * ctx )
nodiscard

Attach a callback for inter-processor NMI dispatch.

Single global callback shared by both NMI units; unit is passed back as a parameter so the callback can demux IPC0NMI vs IPC1NMI. Pass NULL to detach.

Parameters
[in]fnCallback fired by ra8_ipc_dispatch_nmi.
[in]ctxOpaque context forwarded to fn.
Returns
ra8_err_t error code.
Return values
k_ra8_okAlways.
Precondition
Caller is in single-threaded init context (single slot).
IRQs masked at install time if NMI handler is in use.
Postcondition
Subsequent ra8_ipc_dispatch_nmi calls invoke fn.
Previous NMI callback, if any, is no longer called.
Note
Thread safety: not thread-safe (single slot).
See also
ra8_ipc_dispatch_nmi
Since
0.1.0

Definition at line 267 of file ra8_ipc_sem_ring.c.

References k_ra8_ok, s_ipc_nmi_callback, and s_ipc_nmi_context.

◆ ra8_ipc_barrier()

void ra8_ipc_barrier ( void )
inlinestatic

Cross-core data-memory barrier for IPC publish + lock ordering.

Issues a full-system Data Memory Barrier (DMB SY) so a producer's Normal-memory payload and ring-index stores – and the accesses inside an IPCSEM critical section – become observable to the peer core BEFORE the Device-mapped FIFO/IRQ notification (TXD / ISET) or the IPCSEM release the peer wakes on. Without it the Cortex-M85 may post the notification ahead of the SRAM payload store, letting the Cortex-M33 consumer observe the new head index while the payload is still in the write buffer – a stale or torn message. The hand-rolled dual-core mailbox examples open-code the same dsb; this is the reusable-HAL equivalent (a DMB suffices: it orders accesses without waiting for completion the way DSB would).

Returns
void.
Precondition
The IPC peripheral is mapped (no access is performed by this call).
Caller runs on the producing or consuming core (any privilege level).
Postcondition
All memory accesses sequenced before the call are observed before any sequenced after it, by every observer in the system domain.
No architectural state other than memory ordering is affected.
Note
Safe in interrupt context: one barrier instruction, no memory access, no lock taken.
On a host build (RA8_OFF_TARGET) the fake cores share a single-threaded address space, so the barrier compiles to a no-op.
Since
0.1.0

Definition at line 70 of file ra8_ipc_sync.h.

Referenced by ra8_ipc_sem_release(), ra8_ipc_sem_take_timeout(), ra8_ipc_sem_try_take(), ra8_ipc_send_burst(), ra8_ipc_send_event(), ra8_ipc_send_message(), and ra8_ipc_send_message_retry().

◆ ra8_ipc_dispatch()

void ra8_ipc_dispatch ( uint8_t channel)

Drive the event callback for one channel.

Reads STA, masks against the per-channel event mask installed at init, and calls the registered callback if any bits remain. If the dispatched event includes k_ra8_ipc_event_msg_ready the driver pops one word from RXD and passes it to the callback. Decoded per-line callbacks attached via ra8_ipc_attach_event_handler are invoked one per IRQn bit present in the dispatched mask. Finally clears every dispatched event bit via CLR.

Parameters
[in]channelChannel id 0..3.
Precondition
ra8_ipc_init was called for this channel.
A callback was attached via ra8_ipc_attach_handler or per-line ra8_ipc_attach_event_handler (else the call is a no-op apart from clearing the bits).
Postcondition
All dispatched event bits in STA read back as 0.
FIFO advances by one word if RDY was set.
Note
Thread safety: not thread-safe per channel.
See also
ra8_ipc_attach_handler
Since
0.1.0

Definition at line 733 of file ra8_ipc.c.

References r_ipc_channel_regs_t::CLR, internal_ra8_ipc_dispatch_irq_lines(), internal_ra8_ipc_event_to_clr(), k_ra8_ipc_channel_count, k_ra8_ipc_event_msg_ready, k_ra8_ipc_internal_event_full_mask, ra8_ipc_channel(), r_ipc_channel_regs_t::RXD, s_ipc_callback, s_ipc_channels, s_ipc_context, and r_ipc_channel_regs_t::STA.

Referenced by internal_ra8_ipc_isr(), and ipc0_receive_isr().

◆ ra8_ipc_dispatch_nmi()

void ra8_ipc_dispatch_nmi ( uint8_t unit)

Drive the NMI dispatch path for one unit.

Reads NMISTA.NMI; if set, calls the registered NMI callback and writes NMICLR.CLR to acknowledge. Safe to call when no NMI is pending (becomes a no-op).

Parameters
[in]unitNMI unit id 0..1.
Precondition
Called from NMI context (or test harness).
Either a callback is attached, or the dispatch is being used purely to ack a stuck status bit.
Postcondition
NMISTA.NMI reads 0 on next fetch.
Callback was invoked exactly once if it was attached and the NMI was pending.
Note
Thread safety: NMI context.
See also
ra8_ipc_attach_nmi_handler
Since
0.1.0

Definition at line 274 of file ra8_ipc_sem_ring.c.

References internal_ra8_ipc_get_nmi(), k_ra8_ipc_nmi_mask_bit, r_ipc_nmi_regs_t::NMICLR, r_ipc_nmi_regs_t::NMISTA, s_ipc_nmi_callback, and s_ipc_nmi_context.

◆ ra8_ipc_install_isr()

ra8_err_t ra8_ipc_install_isr ( uint8_t unit,
uint8_t priority )
nodiscard

Wire the IPC IRQ event into the ISR table.

Registers ra8_ipc_dispatch_unit against the ELC event for the matching IPC unit (k_ra8_ipc_elc_event_irq0 for unit 0, k_ra8_ipc_elc_event_irq1 for unit 1). The vector trampoline then calls ra8_ipc_dispatch for both channels in the unit (channels 0+1 for unit 0; channels 2+3 for unit 1) so the per-line callbacks fire on every interrupt.

Parameters
[in]unitIPC unit id 0..1.
[in]priorityNVIC priority forwarded to ra8_isr_register.
Returns
ra8_err_t error code.
Return values
k_ra8_okRegistered.
k_ra8_err_invalid_argunit >= 2.
k_ra8_err_no_memra8_isr_register had no free slot.
k_ra8_err_existsAlready installed for that unit.
Precondition
ra8_isr_init has been called.
Caller is in single-threaded init context.
Postcondition
NVIC line for the IPC IRQ is enabled at priority.
IELSR slot for the event is owned by this driver.
Note
Thread safety: not thread-safe.
See also
ra8_ipc_uninstall_isr
Since
0.1.0

Definition at line 804 of file ra8_ipc.c.

References internal_ra8_ipc_isr(), internal_ra8_ipc_unit_to_event(), k_ra8_err_exists, k_ra8_err_invalid_arg, k_ra8_ipc_nmi_unit_count, k_ra8_ok, ra8_isr_register(), and s_ipc_isr_state.

◆ ra8_ipc_nmi_clear()

ra8_err_t ra8_ipc_nmi_clear ( uint8_t unit)
nodiscard

Acknowledge an inter-processor NMI on the local core.

Parameters
[in]unitNMI unit id 0..1.
Returns
ra8_err_t error code.
Return values
k_ra8_okCLR written.
k_ra8_err_invalid_argunit >= 2.
Precondition
IPC NMI registers are mapped.
This core observed NMISTA.NMI = 1.
Postcondition
NMISTA.NMI reads 0 on next fetch.
NMI line into ICU is de-asserted.
Note
Thread safety: re-entrant per unit.
See also
ra8_ipc_nmi_send
Since
0.1.0

Definition at line 243 of file ra8_ipc_sem_ring.c.

References internal_ra8_ipc_get_nmi(), k_ra8_err_invalid_arg, k_ra8_ipc_nmi_mask_bit, k_ra8_ok, and r_ipc_nmi_regs_t::NMICLR.

◆ ra8_ipc_nmi_get_status()

ra8_err_t ra8_ipc_nmi_get_status ( uint8_t unit,
bool * out_pending )
nodiscard

Read NMISTA.NMI for one IPC NMI unit.

Parameters
[in]unitNMI unit id 0..1.
[out]out_pendingReceives true if NMI is currently asserted.
Returns
ra8_err_t error code.
Return values
k_ra8_okStatus read.
k_ra8_err_invalid_argunit >= 2.
k_ra8_err_null_ptrout_pending was NULL.
Precondition
out_pending non-NULL.
IPC NMI registers are mapped.
Postcondition
*out_pending reflects NMISTA.NMI.
No registers are mutated.
Note
Thread safety: re-entrant; pure read.
See also
ra8_ipc_nmi_send
Since
0.1.0

Definition at line 255 of file ra8_ipc_sem_ring.c.

References internal_ra8_ipc_get_nmi(), k_ra8_err_invalid_arg, k_ra8_ipc_nmi_mask_bit, k_ra8_ok, r_ipc_nmi_regs_t::NMISTA, RA8_CHECK_NULL_PTR, and s_tag.

◆ ra8_ipc_nmi_send()

ra8_err_t ra8_ipc_nmi_send ( uint8_t unit)
nodiscard

Issue an inter-processor NMI to the peer core.

Writes 1 to IPCnNMISET.SET (HUM Ch 3.2.5 p 211 / Ch 3.2.8 p 213). The peer core observes IPCnNMISTA.NMI = 1 and (if the ICU has the IPCNMIn line enabled) takes the NMI exception.

Parameters
[in]unitNMI unit id (k_ra8_ipc_unit_ipc0 or k_ra8_ipc_unit_ipc1).
Returns
ra8_err_t error code.
Return values
k_ra8_okSET written.
k_ra8_err_invalid_argunit >= 2.
Precondition
IPC NMI registers are mapped.
Receiving core has unmasked the IPCNMIn vector (or expects to observe NMISTA via polling).
Postcondition
Peer NMISTA.NMI reads 1 until the peer writes NMICLR.CLR.
Local NMISET write occurs exactly once.
Note
Thread safety: re-entrant per unit.
See also
ra8_ipc_nmi_clear
Since
0.1.0

Definition at line 231 of file ra8_ipc_sem_ring.c.

References internal_ra8_ipc_get_nmi(), k_ra8_err_invalid_arg, k_ra8_ipc_nmi_mask_bit, k_ra8_ok, and r_ipc_nmi_regs_t::NMISET.

◆ ra8_ipc_ring_consume()

ra8_err_t ra8_ipc_ring_consume ( ra8_ipc_ring_t * ring,
uint32_t * out_payload )
nodiscard

Pop one word from the shared-memory ring (consumer side).

Acquires the semaphore, samples head/tail, copies slots[tail % capacity] into out_payload if non-empty, advances tail, releases the semaphore.

Parameters
[in]ringNon-NULL initialized descriptor.
[out]out_payloadReceives the popped word.
Returns
ra8_err_t error code.
Return values
k_ra8_okWord dequeued.
k_ra8_err_null_ptrring or out_payload was NULL.
k_ra8_err_busySemaphore not available.
k_ra8_err_no_dataRing was empty.
Precondition
ra8_ipc_ring_init succeeded.
out_payload non-NULL.
Postcondition
On success, tail advanced by 1 (mod 2^32).
On no_data, *out_payload is left untouched.
Note
Thread safety: serialised by the IPCSEM wrapper.
See also
ra8_ipc_ring_produce
Since
0.1.0

Definition at line 380 of file ra8_ipc_sem_ring.c.

References ra8_ipc_ring_t::capacity, ra8_ipc_ring_t::head, k_ra8_err_no_data, k_ra8_ok, RA8_CHECK_NULL_PTR, ra8_ipc_sem_release(), ra8_ipc_sem_try_take(), s_tag, ra8_ipc_ring_t::sem_id, ra8_ipc_ring_t::slots, and ra8_ipc_ring_t::tail.

◆ ra8_ipc_ring_init()

ra8_err_t ra8_ipc_ring_init ( ra8_ipc_ring_t * ring)
nodiscard

Initialise a producer/consumer ring backed by shared SRAM.

Zeroes the head/tail counters and stores the descriptor for later ra8_ipc_ring_produce / ra8_ipc_ring_consume calls. Does not touch the underlying slots array; the caller is responsible for placing it in shared SRAM that both cores can see.

Parameters
[in]ringNon-NULL descriptor (caller-allocated).
Returns
ra8_err_t error code.
Return values
k_ra8_okInitialized.
k_ra8_err_null_ptrring or one of its required pointer fields was NULL.
k_ra8_err_invalid_argcapacity == 0 or non-power-of-two.
Precondition
ring->slots / head / tail non-NULL.
Both cores agree on the descriptor layout.
Postcondition
*ring->head == 0 and *ring->tail == 0.
Ring is empty and ready for ra8_ipc_ring_produce.
Note
Thread safety: caller must serialise init across cores.
See also
ra8_ipc_ring_produce
Since
0.1.0

Definition at line 340 of file ra8_ipc_sem_ring.c.

References ra8_ipc_ring_t::head, internal_ra8_ipc_ring_validate(), k_ra8_ok, RA8_CHECK_NULL_PTR, s_tag, ra8_ipc_ring_t::slots, and ra8_ipc_ring_t::tail.

◆ ra8_ipc_ring_is_empty()

ra8_err_t ra8_ipc_ring_is_empty ( const ra8_ipc_ring_t * ring,
bool * out_empty )
nodiscard

Predicate: ring empty?

Parameters
[in]ringNon-NULL descriptor.
[out]out_emptytrue when head == tail.
Returns
ra8_err_t error code.
Return values
k_ra8_okPredicate evaluated.
k_ra8_err_null_ptrring or out_empty was NULL.
Precondition
ring and out_empty non-NULL.
ring was initialized.
Postcondition
No registers are mutated.
*out_empty reflects head == tail.
Note
Thread safety: re-entrant; pure read.
Since
0.1.0

Definition at line 399 of file ra8_ipc_sem_ring.c.

References ra8_ipc_ring_t::head, k_ra8_ok, RA8_CHECK_NULL_PTR, s_tag, and ra8_ipc_ring_t::tail.

◆ ra8_ipc_ring_is_full()

ra8_err_t ra8_ipc_ring_is_full ( const ra8_ipc_ring_t * ring,
bool * out_full )
nodiscard

Predicate: ring full?

Parameters
[in]ringNon-NULL descriptor.
[out]out_fulltrue when (head - tail) == capacity.
Returns
ra8_err_t error code.
Return values
k_ra8_okPredicate evaluated.
k_ra8_err_null_ptrring or out_full was NULL.
Precondition
ring and out_full non-NULL.
ring was initialized.
Postcondition
No registers are mutated.
*out_full reflects (head - tail) == capacity.
Note
Thread safety: re-entrant; pure read.
Since
0.1.0

Definition at line 407 of file ra8_ipc_sem_ring.c.

References ra8_ipc_ring_t::capacity, ra8_ipc_ring_t::head, k_ra8_ok, RA8_CHECK_NULL_PTR, s_tag, and ra8_ipc_ring_t::tail.

◆ ra8_ipc_ring_produce()

ra8_err_t ra8_ipc_ring_produce ( ra8_ipc_ring_t * ring,
uint32_t payload )
nodiscard

Push one word into the shared-memory ring (producer side).

Acquires ring->sem_id via ra8_ipc_sem_try_take, writes payload into slots[head % capacity], advances head, releases the semaphore, then signals the consumer through ra8_ipc_send_event(ring->channel, ring->notify_id).

Parameters
[in]ringNon-NULL initialized descriptor.
[in]payload32-bit word to enqueue.
Returns
ra8_err_t error code.
Return values
k_ra8_okWord enqueued and notification sent.
k_ra8_err_null_ptrring was NULL.
k_ra8_err_busyRing full or semaphore not available.
Precondition
ra8_ipc_ring_init succeeded.
Producer holds no other contended IPCSEM.
Postcondition
On success, head advanced by 1 (mod 2^32).
On success, IRQ event line was raised on the consumer side.
Note
Thread safety: serialised by the IPCSEM wrapper.
See also
ra8_ipc_ring_consume
Since
0.1.0

Definition at line 355 of file ra8_ipc_sem_ring.c.

References ra8_ipc_ring_t::capacity, ra8_ipc_ring_t::channel, ra8_ipc_ring_t::head, k_ra8_err_busy, k_ra8_ok, ra8_ipc_ring_t::notify_id, RA8_CHECK_NULL_PTR, ra8_ipc_sem_release(), ra8_ipc_sem_try_take(), ra8_ipc_send_event(), s_tag, ra8_ipc_ring_t::sem_id, ra8_ipc_ring_t::slots, and ra8_ipc_ring_t::tail.

◆ ra8_ipc_sem_is_locked()

ra8_err_t ra8_ipc_sem_is_locked ( uint8_t sem_id,
bool * out_locked )
nodiscard

Predicate: is the semaphore currently locked?

Note that simply reading IPCSEMn through a 32-bit access takes the semaphore (HUM Ch 3.2.3 p 210 NOTE). This API therefore samples the LOCK bit by reading and, if the read observed "unlocked", undoes the probe's own take with the write-1-to-clear release command so the register reads back 0 again.

Only safe to call when the caller already owns the lock or knows the peer is quiescent. Most users should treat this as a debug-only helper and stick to ra8_ipc_sem_try_take for real acquisition.

Parameters
[in]sem_idSemaphore index 0..15.
[out]out_lockedReceives true if the semaphore was already locked.
Returns
ra8_err_t error code.
Return values
k_ra8_okPredicate evaluated.
k_ra8_err_invalid_argsem_id >= 16.
k_ra8_err_null_ptrout_locked was NULL.
Precondition
out_locked non-NULL.
Caller is in a single-owner or quiescent context.
Postcondition
Semaphore lock state is restored to its pre-call value.
No interrupt is generated by this call.
Note
Thread safety: NOT safe under contention – diagnostic only.
Since
0.1.0

Definition at line 204 of file ra8_ipc_sem_ring.c.

References internal_ra8_ipc_sem_read_take(), internal_ra8_ipc_sem_release_write(), k_ra8_err_invalid_arg, k_ra8_ipc_sem_count, k_ra8_ok, RA8_CHECK_NULL_PTR, ra8_ipc_sem(), and s_tag.

◆ ra8_ipc_sem_release()

ra8_err_t ra8_ipc_sem_release ( uint8_t sem_id)
nodiscard

Release one IPC hardware semaphore.

Parameters
[in]sem_idSemaphore index 0..15.
Returns
ra8_err_t error code.
Return values
k_ra8_okReleased.
k_ra8_err_invalid_argsem_id >= 16.
Precondition
Caller previously acquired sem_id via ra8_ipc_sem_try_take or ra8_ipc_sem_take_timeout.
IPC base window is mapped.
Postcondition
IPCSEMn.LOCK = 0.
Other waiting cores may now acquire.
Note
Thread safety: re-entrant across cores.
See also
ra8_ipc_sem_try_take
Since
0.1.0

Definition at line 190 of file ra8_ipc_sem_ring.c.

References internal_ra8_ipc_sem_release_write(), k_ra8_err_invalid_arg, k_ra8_ipc_sem_count, k_ra8_ok, RA8_CHECK_NULL_PTR, ra8_ipc_barrier(), ra8_ipc_sem(), and s_tag.

Referenced by ra8_ipc_ring_consume(), and ra8_ipc_ring_produce().

◆ ra8_ipc_sem_take_timeout()

ra8_err_t ra8_ipc_sem_take_timeout ( uint8_t sem_id,
uint16_t max_spins )
nodiscard

Bounded-spin take on one IPC hardware semaphore.

Parameters
[in]sem_idSemaphore index 0..15.
[in]max_spinsIteration cap (<= k_ra8_ipc_sem_take_max).
Returns
ra8_err_t error code.
Return values
k_ra8_okAcquired before the budget ran out.
k_ra8_err_invalid_argsem_id >= 16.
k_ra8_err_hw_timeoutBudget expired without acquiring.
Precondition
IPC base window is mapped.
max_spins non-zero.
Postcondition
On success, IPCSEMn.LOCK = 1.
On timeout, semaphore state is unchanged from last spin.
Note
Thread safety: re-entrant across cores.
See also
ra8_ipc_sem_try_take
Since
0.1.0

Definition at line 163 of file ra8_ipc_sem_ring.c.

References internal_ra8_ipc_sem_read_take(), k_ra8_err_hw_timeout, k_ra8_err_invalid_arg, k_ra8_ipc_sem_count, k_ra8_ipc_sem_take_max, k_ra8_ok, RA8_CHECK_NULL_PTR, ra8_ipc_barrier(), ra8_ipc_sem(), and s_tag.

◆ ra8_ipc_sem_try_take()

ra8_err_t ra8_ipc_sem_try_take ( uint8_t sem_id)
nodiscard

Test-and-set acquire on one IPC hardware semaphore.

IPCSEMn implements test-and-set semantics: a 32-bit read sets the LOCK bit and returns the previous value. A return of 0 means the caller acquired the lock (it was previously unlocked). A return of 1 means another core owned it.

Parameters
[in]sem_idSemaphore index 0..15.
Returns
ra8_err_t error code.
Return values
k_ra8_okLock acquired.
k_ra8_err_busyLock already held by another core.
k_ra8_err_invalid_argsem_id >= 16.
Precondition
IPC base window is mapped.
Caller is prepared to handle k_ra8_err_busy by retry or back-off.
Postcondition
On success, IPCSEMn.LOCK = 1.
On busy, no register write or release is implied.
Note
Thread safety: re-entrant across cores – this is the whole point.
See also
ra8_ipc_sem_release
Since
0.1.0

Definition at line 143 of file ra8_ipc_sem_ring.c.

References internal_ra8_ipc_sem_read_take(), k_ra8_err_busy, k_ra8_err_invalid_arg, k_ra8_ipc_sem_count, k_ra8_ok, RA8_CHECK_NULL_PTR, ra8_ipc_barrier(), ra8_ipc_sem(), and s_tag.

Referenced by ra8_ipc_ring_consume(), and ra8_ipc_ring_produce().

◆ ra8_ipc_uninstall_isr()

ra8_err_t ra8_ipc_uninstall_isr ( uint8_t unit)
nodiscard

Tear down a previously installed IPC ISR.

Parameters
[in]unitIPC unit id 0..1.
Returns
ra8_err_t error code.
Return values
k_ra8_okUnregistered.
k_ra8_err_invalid_argunit >= 2.
k_ra8_err_not_foundWas not installed.
Precondition
Caller is in single-threaded shutdown context.
IRQs masked.
Postcondition
NVIC line for the IPC IRQ is disabled.
Driver no longer owns an IELSR slot for the unit.
Note
Thread safety: not thread-safe.
See also
ra8_ipc_install_isr
Since
0.1.0

Definition at line 832 of file ra8_ipc.c.

References internal_ra8_ipc_unit_to_event(), k_ra8_err_invalid_arg, k_ra8_err_not_found, k_ra8_ipc_nmi_unit_count, k_ra8_ok, ra8_isr_unregister(), and s_ipc_isr_state.