|
ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
|
Mutex and semaphore vtable slots. More...
#include <stddef.h>#include <stdint.h>#include <string.h>#include "ra8_attributes.h"#include "ra8_check.h"#include "ra8_err.h"#include "ra8_esp_hosted_port.h"#include "ra8_esp_hosted_rtos_internal.h"#include "ra8_log.h"#include "tx_api.h"#include "port_esp_hosted_host_os.h"Go to the source code of this file.
Data Structures | |
| struct | ra8_esp_hosted_sync_state_t |
| Module state of the mutex and semaphore half – entirely static. More... | |
Enumerations | |
| enum | ra8_esp_hosted_sync_const_t : uint32_t { k_ra8_esp_hosted_sem_initial = 1U } |
| Numeric constants of the mutex and semaphore half. More... | |
Functions | |
| static void * | internal_h_create_mutex (void) |
| Create a mutex from the fixed mutex table. | |
| static int | internal_h_lock_mutex (void *mutex_handle, int timeout_ms) |
| Take a mutex, blocking for at most timeout_ms. | |
| static int | internal_h_unlock_mutex (void *mutex_handle) |
| Release a mutex the caller owns. | |
| static int | internal_h_destroy_mutex (void *mutex_handle) |
| Delete a mutex and free its table row. | |
| static void * | internal_h_create_semaphore (int max_count) |
| Create a counting semaphore from the fixed semaphore table. | |
| static int | internal_h_get_semaphore (void *semaphore_handle, int timeout_ms) |
| Take a semaphore, blocking for at most timeout_ms. | |
| static int | internal_h_post_semaphore (void *semaphore_handle) |
| Post a semaphore from thread context. | |
| static int | internal_h_post_semaphore_from_isr (void *semaphore_handle) |
| Post a semaphore from an interrupt handler. | |
| static int | internal_h_destroy_semaphore (void *semaphore_handle) |
| Delete a semaphore and free its table row. | |
| ra8_err_t | priv_ra8_esp_hosted_rtos_sync_init (void) |
| Clear the mutex and semaphore tables and mark them usable. | |
| ra8_err_t | priv_ra8_esp_hosted_rtos_sync_deinit (void) |
| Delete every outstanding mutex and semaphore. | |
| ra8_err_t | priv_ra8_esp_hosted_rtos_bind_sync (hosted_osi_funcs_t *out) |
| Populate the mutex and semaphore slots of the vtable. | |
Variables | |
| static const char * | s_tag = "ESPH_SYNC" |
| Log tag for the mutex and semaphore half of the port. | |
| static ra8_esp_hosted_sync_state_t | s_sync |
| Singleton state of the mutex and semaphore half. | |
Mutex and semaphore vtable slots.
See port/esp-hosted/src/ra8_esp_hosted_rtos_internal.h for the contracts. The RTOS slice is three translation units because one would be several times the project's thousand-line file cap; the split follows the object kinds, which is also how the fixed tables divide. This unit owns the mutex and semaphore tables.
There are no mempool-lock rows to fill: H_USE_MEMPOOL is deliberately hosted_osi_funcs_t at all. See port_esp_hosted_host_config.h for why – the vendored header guards them with #ifdef rather than #if, so any definition, including zero, would switch them on and make the struct layout depend on include order.
Definition in file ra8_esp_hosted_rtos_sync.c.
| enum ra8_esp_hosted_sync_const_t : uint32_t |
Numeric constants of the mutex and semaphore half.
One value, stated here rather than inline so the create-time semaphore count is impossible to change by accident.
| Enumerator | |
|---|---|
| k_ra8_esp_hosted_sem_initial | Instances a new semaphore starts with. |
Definition at line 71 of file ra8_esp_hosted_rtos_sync.c.
|
static |
Create a mutex from the fixed mutex table.
Priority inheritance is enabled: the bus lock is taken by both the transaction thread and a lower-priority power-save path, which is exactly the inversion ThreadX's inheritance exists to bound.
| nullptr | The substrate is down or the mutex table is full. |
| non-null | A handle usable with the other mutex slots. |
Definition at line 128 of file ra8_esp_hosted_rtos_sync.c.
References k_ra8_esp_hosted_max_mutexes, priv_ra8_esp_hosted_rtos_slot_take(), RA8_INTERNAL, ra8_log_error, s_sync, s_tag, tx_mutex_create, and TX_SUCCESS.
Referenced by priv_ra8_esp_hosted_rtos_bind_sync().
|
static |
Create a counting semaphore from the fixed semaphore table.
The initial count is one, not max_count. Every call site in the vendored tree – bus_init_internal in spi_drv.c, rpc_platform_init, rpc_core's per-request semaphore – follows the create immediately with one _h_get_semaphore(sem, 0) whose own comment says it is there to leave the semaphore empty so the waiting task blocks. Starting at max_count would leave max_count - 1 phantom instances behind that single drain, and spi_drv.c reads a successful take as "a transmit message is present as per sem" – so the phantom counts would make it repeatedly believe a frame is queued when none is. Starting at one makes that drain do exactly what its comment claims on every path, binary or counting. max_count is therefore validated and otherwise unused: ThreadX counting semaphores carry no ceiling.
| [in] | max_count | Largest count the caller intends to reach; must be positive. |
| nullptr | The substrate is down, max_count was not positive, or the semaphore table is full. |
| non-null | A handle usable with the other semaphore slots. |
Definition at line 273 of file ra8_esp_hosted_rtos_sync.c.
References k_ra8_esp_hosted_max_semaphores, k_ra8_esp_hosted_sem_initial, priv_ra8_esp_hosted_rtos_slot_take(), RA8_INTERNAL, ra8_log_error, s_sync, s_tag, and TX_SUCCESS.
Referenced by priv_ra8_esp_hosted_rtos_bind_sync().
|
static |
Delete a mutex and free its table row.
Frees the row last so a concurrent lookup never sees a half-deleted object.
| [in] | mutex_handle | Handle from _h_create_mutex. |
| RET_OK | The mutex is gone and its row is free. |
| RET_INVALID | The handle was not usable. |
| RET_FAIL | ThreadX refused the delete. |
Definition at line 227 of file ra8_esp_hosted_rtos_sync.c.
References k_ra8_esp_hosted_max_mutexes, priv_ra8_esp_hosted_rtos_slot_index(), RA8_INTERNAL, RET_FAIL, RET_INVALID, RET_OK, s_sync, tx_mutex_delete, and TX_SUCCESS.
Referenced by priv_ra8_esp_hosted_rtos_bind_sync(), and priv_ra8_esp_hosted_rtos_sync_deinit().
|
static |
Delete a semaphore and free its table row.
Frees the row last so a concurrent lookup never sees a half-deleted object.
| [in] | semaphore_handle | Handle from _h_create_semaphore. |
| RET_OK | The semaphore is gone and its row is free. |
| RET_INVALID | The handle was not usable. |
| RET_FAIL | ThreadX refused the delete. |
Definition at line 405 of file ra8_esp_hosted_rtos_sync.c.
References k_ra8_esp_hosted_max_semaphores, priv_ra8_esp_hosted_rtos_slot_index(), RA8_INTERNAL, RET_FAIL, RET_INVALID, RET_OK, s_sync, and TX_SUCCESS.
Referenced by priv_ra8_esp_hosted_rtos_bind_sync(), and priv_ra8_esp_hosted_rtos_sync_deinit().
|
static |
Take a semaphore, blocking for at most timeout_ms.
A zero timeout is a non-blocking try-take that returns RET_OK on success – spi_drv.c spells it if (!_h_get_semaphore(sem, 0)) and treats the zero as "an item is queued", so the mapping is load-bearing.
| [in] | semaphore_handle | Handle from _h_create_semaphore. |
| [in] | timeout_ms | Wait in milliseconds; 0 = try, negative = forever. |
| RET_OK | An instance was taken. |
| RET_INVALID | The handle was not usable. |
| RET_FAIL_TIMEOUT | The count stayed zero for the whole wait. |
Definition at line 311 of file ra8_esp_hosted_rtos_sync.c.
References k_ra8_esp_hosted_max_semaphores, priv_ra8_esp_hosted_rtos_ms_to_ticks(), priv_ra8_esp_hosted_rtos_slot_index(), RA8_INTERNAL, RET_FAIL_TIMEOUT, RET_INVALID, RET_OK, s_sync, and TX_SUCCESS.
Referenced by priv_ra8_esp_hosted_rtos_bind_sync().
|
static |
Take a mutex, blocking for at most timeout_ms.
Zero milliseconds is a try-lock; a negative value, which is how HOSTED_BLOCK_MAX arrives through an int, blocks until the mutex is free.
| [in] | mutex_handle | Handle from _h_create_mutex. |
| [in] | timeout_ms | Wait in milliseconds; 0 = try, negative = forever. |
| RET_OK | The caller now owns the mutex. |
| RET_INVALID | The handle was not usable. |
| RET_FAIL_TIMEOUT | The wait expired with the mutex still held. |
Definition at line 165 of file ra8_esp_hosted_rtos_sync.c.
References k_ra8_esp_hosted_max_mutexes, priv_ra8_esp_hosted_rtos_ms_to_ticks(), priv_ra8_esp_hosted_rtos_slot_index(), RA8_INTERNAL, RET_FAIL_TIMEOUT, RET_INVALID, RET_OK, s_sync, tx_mutex_get, and TX_SUCCESS.
Referenced by priv_ra8_esp_hosted_rtos_bind_sync().
|
static |
Post a semaphore from thread context.
Increments the count and, if a thread is blocked on it, releases that thread. ThreadX imposes no ceiling, so a post always succeeds on a live semaphore.
| [in] | semaphore_handle | Handle from _h_create_semaphore. |
| RET_OK | The count was incremented. |
| RET_INVALID | The handle was not usable. |
| RET_FAIL | ThreadX refused the post. |
Definition at line 344 of file ra8_esp_hosted_rtos_sync.c.
References k_ra8_esp_hosted_max_semaphores, priv_ra8_esp_hosted_rtos_slot_index(), RA8_INTERNAL, RET_FAIL, RET_INVALID, RET_OK, s_sync, and TX_SUCCESS.
Referenced by priv_ra8_esp_hosted_rtos_bind_sync().
|
static |
Post a semaphore from an interrupt handler.
Called from the HANDSHAKE and DATA_READY edge handlers. It does exactly what the thread-context post does, because tx_semaphore_put is itself ISR-safe – and deliberately nothing else: no logging, no blocking, no allocation, so the handler stays bounded.
| [in] | semaphore_handle | Handle from _h_create_semaphore. |
| RET_OK | The count was incremented. |
| RET_INVALID | The handle was not usable. |
| RET_FAIL | ThreadX refused the post. |
Definition at line 375 of file ra8_esp_hosted_rtos_sync.c.
References k_ra8_esp_hosted_max_semaphores, priv_ra8_esp_hosted_rtos_slot_index(), RA8_INTERNAL, RA8_ISR_SAFE, RET_FAIL, RET_INVALID, RET_OK, s_sync, and TX_SUCCESS.
Referenced by priv_ra8_esp_hosted_rtos_bind_sync().
|
static |
Release a mutex the caller owns.
Reports a distinct failure for an unbalanced release rather than swallowing it, because that is always a defect in the caller.
| [in] | mutex_handle | Handle from _h_create_mutex. |
| RET_OK | The ownership depth fell by one. |
| RET_INVALID | The handle was not usable. |
| RET_FAIL | The caller did not own the mutex. |
Definition at line 197 of file ra8_esp_hosted_rtos_sync.c.
References k_ra8_esp_hosted_max_mutexes, priv_ra8_esp_hosted_rtos_slot_index(), RA8_INTERNAL, RET_FAIL, RET_INVALID, RET_OK, s_sync, tx_mutex_put, and TX_SUCCESS.
Referenced by priv_ra8_esp_hosted_rtos_bind_sync().
| ra8_err_t priv_ra8_esp_hosted_rtos_bind_sync | ( | hosted_osi_funcs_t * | out | ) |
Populate the mutex and semaphore slots of the vtable.
The binder of the synchronisation translation unit, which owns the mutex and semaphore tables. Called by priv_ra8_esp_hosted_osi_bind_all alongside the other two binders. There are no mempool-lock rows to fill; see the file-level note on H_USE_MEMPOOL.
| [out] | out | Vtable to populate. Must be non-null. |
| k_ra8_ok | Every mutex and semaphore slot is populated. |
| k_ra8_err_null_ptr | out was null. |
Definition at line 452 of file ra8_esp_hosted_rtos_sync.c.
References internal_h_create_mutex(), internal_h_create_semaphore(), internal_h_destroy_mutex(), internal_h_destroy_semaphore(), internal_h_get_semaphore(), internal_h_lock_mutex(), internal_h_post_semaphore(), internal_h_post_semaphore_from_isr(), internal_h_unlock_mutex(), k_ra8_ok, RA8_CHECK_NULL_PTR, and s_tag.
Referenced by priv_ra8_esp_hosted_osi_bind_all().
|
nodiscard |
Delete every outstanding mutex and semaphore.
The synchronisation half of priv_ra8_esp_hosted_rtos_deinit: walks both tables and deletes whatever is still in use, then clears the state so a later create fails cleanly rather than touching a dead control block.
| k_ra8_ok | Every object was released. |
| k_ra8_err_not_initialized | The tables were not initialised. |
| k_ra8_err_rtos_error | ThreadX refused a delete. |
Definition at line 431 of file ra8_esp_hosted_rtos_sync.c.
References internal_h_destroy_mutex(), internal_h_destroy_semaphore(), k_ra8_err_not_initialized, k_ra8_err_rtos_error, k_ra8_esp_hosted_max_mutexes, k_ra8_esp_hosted_max_semaphores, k_ra8_ok, memset(), ra8_log_error, RET_OK, s_sync, and s_tag.
Referenced by priv_ra8_esp_hosted_rtos_deinit().
|
nodiscard |
Clear the mutex and semaphore tables and mark them usable.
The synchronisation half of priv_ra8_esp_hosted_rtos_init. Separated so the unit that owns the tables also owns their lifecycle, and so a test can bring the locks up without the allocator.
| k_ra8_ok | Both tables are empty and usable. |
| k_ra8_err_invalid_state | The tables were already initialised. |
Definition at line 420 of file ra8_esp_hosted_rtos_sync.c.
References k_ra8_err_invalid_state, k_ra8_ok, memset(), ra8_log_error, s_sync, and s_tag.
Referenced by priv_ra8_esp_hosted_rtos_init().
|
static |
Singleton state of the mutex and semaphore half.
Zero-initialised at link time; brought up by priv_ra8_esp_hosted_rtos_sync_init.
Definition at line 107 of file ra8_esp_hosted_rtos_sync.c.
Referenced by internal_h_create_mutex(), internal_h_create_semaphore(), internal_h_destroy_mutex(), internal_h_destroy_semaphore(), internal_h_get_semaphore(), internal_h_lock_mutex(), internal_h_post_semaphore(), internal_h_post_semaphore_from_isr(), internal_h_unlock_mutex(), priv_ra8_esp_hosted_rtos_sync_deinit(), and priv_ra8_esp_hosted_rtos_sync_init().
|
static |
Log tag for the mutex and semaphore half of the port.
Shared by every diagnostic this translation unit emits.
Definition at line 53 of file ra8_esp_hosted_rtos_sync.c.