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

IPC HAL – hardware semaphores, NMI surface, and ring buffers. More...

#include <stdint.h>
#include "ra8_attributes.h"
#include "ra8_check.h"
#include "ra8_err.h"
#include "ra8_hw_err.h"
#include "ra8_ipc.h"
#include "ra8_ipc_regs.h"
Include dependency graph for ra8_ipc_sem_ring.c:

Go to the source code of this file.

Functions

static volatile r_ipc_nmi_regs_tinternal_ra8_ipc_get_nmi (uint8_t unit)
 Validate NMI unit id and return the NMI reg pointer.
static uint32_t internal_ra8_ipc_sem_read_take (volatile uint32_t *sem)
 Test-and-set on IPCSEMn – a 32-bit read takes the lock and returns the previous LOCK value.
static void internal_ra8_ipc_sem_release_write (volatile uint32_t *sem)
 Write the IPCSEMn write-1-to-clear release command.
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.
static ra8_err_t internal_ra8_ipc_ring_validate (const ra8_ipc_ring_t *ring)
 Validate the scalar fields of an ra8_ipc_ring_t descriptor.
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?

Variables

static const char * s_tag = "IPC"
static ra8_ipc_nmi_fn_t s_ipc_nmi_callback
static void * s_ipc_nmi_context

Detailed Description

IPC HAL – hardware semaphores, NMI surface, and ring buffers.

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

Sibling translation unit of ra8_ipc.c carrying the cohesive lower-level IPC surfaces that compose into cross-core synchronization: the IPCSEM0..15 hardware-semaphore wrappers (test-and-set + bounded spin take), the NMI surface (IPC0NMI* / IPC1NMI*), and the producer/consumer ring-buffer protocol that uses an IPCSEM for mutual exclusion plus the FIFO IRQ lines for cross-core notification. See ra8_ipc.h for the public API surface. Each register access carries a HUM Ch 3 citation – IPC is not power-gated by MSTPCR so the driver does not call ra8_mstp_*.

Since
0.1.0

Definition in file ra8_ipc_sem_ring.c.

Function Documentation

◆ internal_ra8_ipc_get_nmi()

volatile r_ipc_nmi_regs_t * internal_ra8_ipc_get_nmi ( uint8_t unit)
static

Validate NMI unit id and return the NMI reg pointer.

Definition at line 47 of file ra8_ipc_sem_ring.c.

References k_ra8_ipc_nmi_unit_count, and ra8_ipc_nmi().

Referenced by ra8_ipc_dispatch_nmi(), ra8_ipc_nmi_clear(), ra8_ipc_nmi_get_status(), and ra8_ipc_nmi_send().

◆ internal_ra8_ipc_ring_validate()

ra8_err_t internal_ra8_ipc_ring_validate ( const ra8_ipc_ring_t * ring)
static

Validate the scalar fields of an ra8_ipc_ring_t descriptor.

Parameters
[in]ringCaller-supplied, null-checked ring descriptor.
Returns
k_ra8_ok if every field is in range, else k_ra8_err_invalid_arg.
Precondition
ring != nullptr.
ring->slots / head / tail are non-null.
Postcondition
No side effects.

See implementation.

Return values
k_ra8_okOperation succeeded.
Postcondition
Caller-visible state matches the documented contract.
Note
Not thread-safe unless documented otherwise.
Since
0.1.0

Definition at line 319 of file ra8_ipc_sem_ring.c.

References ra8_ipc_ring_t::capacity, ra8_ipc_ring_t::channel, k_ra8_err_invalid_arg, k_ra8_ipc_channel_count, k_ra8_ipc_irq_event_count, k_ra8_ipc_sem_count, k_ra8_ok, ra8_ipc_ring_t::notify_id, and ra8_ipc_ring_t::sem_id.

Referenced by ra8_ipc_ring_init().

◆ internal_ra8_ipc_sem_read_take()

uint32_t internal_ra8_ipc_sem_read_take ( volatile uint32_t * sem)
static

Test-and-set on IPCSEMn – a 32-bit read takes the lock and returns the previous LOCK value.

On silicon the read itself is the take: HUM Ch 3.2.3 "IPCSEMn" p 210 documents "Set condition: Reading this register", and the read data report the LOCK state from before the set. The host unit-test register file is dumb RAM with no read side effects, so the host test build routes the same read through the ra8_fake_mmio read-to-set model, which performs the read and then latches LOCK in the backing RAM exactly as the silicon set condition does. A test models a peer core releasing the semaphore mid-spin with ra8_fake_mmio_set_poll_hook.

Parameters
[in]semMapped IPCSEMn register. Must not be NULL (callers null-check the accessor result before calling).
Returns
The LOCK bit as read before the take side effect.
Return values
0The semaphore was free – the caller now owns it.
k_ra8_ipc_sem_mask_lockIt was already owned by another core.
Precondition
sem points at a mapped IPCSEMn register.
The caller validated sem_id against k_ra8_ipc_sem_count.
Postcondition
LOCK is set in the register (silicon set condition / host model).
No other register state is modified.
Note
ISR-safe: the take is a single 32-bit read on silicon.
Since
0.1.0

Definition at line 85 of file ra8_ipc_sem_ring.c.

References k_ra8_ipc_sem_mask_lock.

Referenced by ra8_ipc_sem_is_locked(), ra8_ipc_sem_take_timeout(), and ra8_ipc_sem_try_take().

◆ internal_ra8_ipc_sem_release_write()

void internal_ra8_ipc_sem_release_write ( volatile uint32_t * sem)
static

Write the IPCSEMn write-1-to-clear release command.

HUM Ch 3.2.3 "IPCSEMn" p 210: "Clear condition: Writing 1 to this bit" – silicon clears LOCK when the command lands. The host unit-test register file is dumb RAM that would store the literal 1 (leaving the register file claiming "locked" after a release), so the host test build routes the same write through the ra8_fake_mmio write-1-to-clear model, which leaves LOCK cleared exactly as silicon does.

Parameters
[in]semMapped IPCSEMn register. Must not be NULL (callers null-check the accessor result before calling).
Precondition
sem points at a mapped IPCSEMn register.
The caller owns the semaphore (its last read-take returned 0).
Postcondition
LOCK reads back 0 (released) on silicon and on the host model.
No other register state is modified.
Note
ISR-safe: the release is a single 32-bit write on silicon.
Since
0.1.0

Definition at line 124 of file ra8_ipc_sem_ring.c.

References k_ra8_ipc_sem_mask_lock.

Referenced by ra8_ipc_sem_is_locked(), and ra8_ipc_sem_release().

◆ 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_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_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().

Variable Documentation

◆ s_ipc_nmi_callback

ra8_ipc_nmi_fn_t s_ipc_nmi_callback
static

Definition at line 35 of file ra8_ipc_sem_ring.c.

Referenced by ra8_ipc_attach_nmi_handler(), and ra8_ipc_dispatch_nmi().

◆ s_ipc_nmi_context

void* s_ipc_nmi_context
static

Definition at line 36 of file ra8_ipc_sem_ring.c.

Referenced by ra8_ipc_attach_nmi_handler(), and ra8_ipc_dispatch_nmi().

◆ s_tag

const char* s_tag = "IPC"
static

Definition at line 33 of file ra8_ipc_sem_ring.c.