|
ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
|
Thread, sleep, timer and clock vtable slots, plus the bind entry. More...
#include <stddef.h>#include <stdint.h>#include <string.h>#include "ra8_attributes.h"#include "ra8_cgc.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_thread_slot_t |
| One row of the fixed thread table. More... | |
| struct | ra8_esp_hosted_timer_slot_t |
| One row of the fixed timer table. More... | |
| struct | ra8_esp_hosted_rtos_state_t |
| Module state of the thread, timer and clock half – entirely static. More... | |
Typedefs | |
| typedef void(* | ra8_esp_hosted_thread_entry_t) (void const *arg) |
| Signature of the thread body the vendored core hands to the port. | |
| typedef void(* | ra8_esp_hosted_timer_cb_t) (void *arg) |
| Signature of the expiry callback the vendored core hands to the port. | |
Enumerations | |
| enum | ra8_esp_hosted_rtos_const_t : uint32_t { k_ra8_esp_hosted_ms_per_tick = 1U , k_ra8_esp_hosted_us_per_ms = 1000U , k_ra8_esp_hosted_ms_per_sec = 1000U , k_ra8_esp_hosted_hz_per_mhz = 1000000U , k_ra8_esp_hosted_spin_cycles_per_iter = 4U , k_ra8_esp_hosted_spin_iters_max = 250000U , k_ra8_esp_hosted_delay_iters_max = 1000000U , k_ra8_esp_hosted_default_cpu_hz = 1000000000U , k_ra8_esp_hosted_thread_stack_bytes = 5120U , k_ra8_esp_hosted_name_max = 16U } |
| Numeric constants of the object tables, sleeps and spin sizing. More... | |
Functions | |
| uint32_t | priv_ra8_esp_hosted_rtos_slot_take (bool *used, uint32_t count) |
| Claim the first free row of an occupancy bitmap. | |
| uint32_t | priv_ra8_esp_hosted_rtos_slot_index (const void *handle, const void *base, size_t stride, uint32_t count, const bool *used) |
| Resolve an opaque handle to its row index in a fixed table. | |
| static void | internal_copy_name (char *dst, size_t cap, const char *src) |
| Copy a caller-supplied object name into a fixed buffer. | |
| static void | internal_thread_entry (ULONG index) |
| ThreadX entry shim that calls the core-supplied thread body. | |
| static void | internal_timer_expiry (ULONG index) |
| ThreadX expiry shim that calls the core-supplied timer callback. | |
| static void | internal_spin_us (uint32_t usec) |
| Burn a bounded number of core cycles standing in for a short delay. | |
| uint32_t | priv_ra8_esp_hosted_rtos_ms_to_ticks (int timeout_ms) |
| Convert an esp-hosted millisecond timeout to a ThreadX wait option. | |
| uint32_t | priv_ra8_esp_hosted_rtos_us_spin_iters (uint32_t cpu_hz, uint32_t usec) |
| Size the busy-wait loop that stands in for a microsecond delay. | |
| static void * | internal_h_thread_create (const char *tname, uint32_t tprio, uint32_t tstack_size, ra8_esp_hosted_thread_entry_t start_routine, void *sr_arg) |
| Start a thread from the fixed thread table. | |
| static int | internal_h_thread_cancel (void *thread_handle) |
| Terminate and delete a thread, freeing its table row. | |
| static void | internal_h_thread_yield (void) |
| Give up the remainder of the current time slice. | |
| static unsigned int | internal_h_msleep (unsigned int mseconds) |
| Sleep the calling thread for a whole number of milliseconds. | |
| static unsigned int | internal_h_sleep (unsigned int seconds) |
| Sleep the calling thread for a whole number of seconds. | |
| static unsigned int | internal_h_usleep (unsigned int useconds) |
| Delay for a number of microseconds, honestly. | |
| static unsigned int | internal_h_blocking_delay (unsigned int number) |
| Busy-delay for a bounded number of loop iterations. | |
| static void * | internal_h_timer_start (const char *name, int duration_ms, int type, ra8_esp_hosted_timer_cb_t timeout_handler, void *arg) |
| Create and start a software timer. | |
| static int | internal_h_timer_stop (void *timer_handle) |
| Stop a timer and free its table row. | |
| static uint64_t | internal_h_get_time_ms (void) |
| Read milliseconds since kernel start, without a 32-bit wrap. | |
| bool | priv_ra8_esp_hosted_rtos_is_ready (void) |
| Report whether the RTOS substrate is currently initialised. | |
| ra8_err_t | priv_ra8_esp_hosted_rtos_init (void) |
| Bring the RTOS substrate up: byte pools and empty object tables. | |
| ra8_err_t | priv_ra8_esp_hosted_rtos_deinit (void) |
| Tear the RTOS substrate down, deleting every outstanding object. | |
| ra8_err_t | priv_ra8_esp_hosted_rtos_bind (hosted_osi_funcs_t *out) |
| Populate the thread, sleep, timer and clock slots of the vtable. | |
Variables | |
| static const char * | s_tag = "ESPH_RTOS" |
| Log tag for the synchronisation half of the port. | |
| static ra8_esp_hosted_rtos_state_t | s_rtos |
| Singleton state of the thread, timer and clock half. | |
| static uint8_t | s_thread_stacks [k_ra8_esp_hosted_max_threads][k_ra8_esp_hosted_thread_stack_bytes] |
| Fixed stack storage, one region per thread table row. | |
Thread, sleep, timer and clock vtable slots, plus the bind entry.
See port/esp-hosted/src/ra8_esp_hosted_rtos_internal.h for the contracts. Every kernel object the vendored core asks for is taken from a fixed table in this translation unit – there is no heap on this board – and the handles the core stores are the addresses of those table rows. The memory and queue halves live in ra8_esp_hosted_rtos_pool.c, which also owns the host-build ThreadX model's shared state.
Definition in file ra8_esp_hosted_rtos.c.
| typedef void(* ra8_esp_hosted_thread_entry_t) (void const *arg) |
Signature of the thread body the vendored core hands to the port.
Named rather than spelled inline at every use so the thread table row and the _h_thread_create slot cannot drift apart, and so neither declaration carries a nested function-pointer parameter that hides the enclosing function's own name from a reader – or from the MC/DC citation checker, which anchors a decision to the function it sits in.
| [in] | arg | The sr_arg the core supplied at creation. |
Definition at line 97 of file ra8_esp_hosted_rtos.c.
| typedef void(* ra8_esp_hosted_timer_cb_t) (void *arg) |
Signature of the expiry callback the vendored core hands to the port.
The mirror of ra8_esp_hosted_thread_entry_t for timers; it takes a mutable void* because that is what the core's own timer contract states.
| [in] | arg | The arg the core supplied at start. |
Definition at line 113 of file ra8_esp_hosted_rtos.c.
| enum ra8_esp_hosted_rtos_const_t : uint32_t |
Numeric constants of the object tables, sleeps and spin sizing.
Collected here so the timing assumptions the port makes are stated once and are visible to anyone changing the kernel tick rate.
Definition at line 67 of file ra8_esp_hosted_rtos.c.
|
static |
Copy a caller-supplied object name into a fixed buffer.
ThreadX keeps the name pointer rather than the characters, so the port must own storage that outlives the caller's literal. Truncates rather than refusing: a shortened diagnostic name is never worth failing a create.
The copy is a bounded character loop that writes the terminator itself rather than a strlen-then-memcpy pair. The name comes from the vendored core, so it may be longer than cap or – on a corrupted caller – unterminated; this form reads at most cap bytes of it either way, and the terminator is written on every path instead of being inferred from a preceding memset.
| [out] | dst | Destination buffer. |
| [in] | cap | Destination capacity in bytes, including the terminator. |
| [in] | src | Name to copy; a null pointer yields an empty name. |
Definition at line 271 of file ra8_esp_hosted_rtos.c.
References memset(), and RA8_INTERNAL.
Referenced by internal_h_thread_create(), and internal_h_timer_start().
|
static |
Busy-delay for a bounded number of loop iterations.
Deliberately not a time unit: upstream's contract for this slot is a raw spin count for the few places the scheduler must not run. The count is clamped so the loop stays statically bounded.
| [in] | number | Iterations requested. |
| number | Always; the return echoes the request, as upstream's does. |
Definition at line 608 of file ra8_esp_hosted_rtos.c.
References internal_h_blocking_delay(), and k_ra8_esp_hosted_delay_iters_max.
Referenced by internal_h_blocking_delay(), and priv_ra8_esp_hosted_rtos_bind().
|
static |
Read milliseconds since kernel start, without a 32-bit wrap.
tx_time_get returns a 32-bit tick count that wraps after about 49.7 days at a 1 kHz tick, and the vendored core uses this value for elapsed-time arithmetic that a wrap would silently corrupt. Each call compares the new reading against the previous one and, when it has gone backwards, adds one full 2^32-tick epoch to a 64-bit accumulator. The detection holds as long as this is called at least once per epoch, which the transport's per-transaction use guarantees by a very wide margin.
| 0 | The kernel has just started and the substrate is down. |
| 1..UINT64_MAX | The extended millisecond count. |
Definition at line 745 of file ra8_esp_hosted_rtos.c.
References k_ra8_esp_hosted_ms_per_tick, RA8_INTERNAL, s_rtos, and tx_time_get.
Referenced by priv_ra8_esp_hosted_rtos_bind().
|
static |
Sleep the calling thread for a whole number of milliseconds.
One kernel tick is one millisecond, so the conversion is the identity; a zero request still yields, which is what the core expects of a zero-length sleep in a polling loop.
| [in] | mseconds | Milliseconds to sleep. |
| mseconds | Always; ThreadX does not report a short sleep. |
Definition at line 528 of file ra8_esp_hosted_rtos.c.
References k_ra8_esp_hosted_ms_per_tick, RA8_INTERNAL, s_rtos, and tx_thread_sleep.
Referenced by internal_h_sleep(), internal_h_usleep(), and priv_ra8_esp_hosted_rtos_bind().
|
static |
Sleep the calling thread for a whole number of seconds.
Converts to milliseconds and reuses the millisecond sleep, so there is one place the tick rate is applied.
| [in] | seconds | Seconds to sleep. |
| seconds | Always; ThreadX does not report a short sleep. |
Definition at line 550 of file ra8_esp_hosted_rtos.c.
References internal_h_msleep(), k_ra8_esp_hosted_ms_per_sec, and RA8_INTERNAL.
Referenced by priv_ra8_esp_hosted_rtos_bind().
|
static |
Terminate and delete a thread, freeing its table row.
Terminates before deleting, which is what ThreadX requires of a running thread, and frees the row last so a concurrent lookup never sees a half-deleted object.
| [in] | thread_handle | Handle from _h_thread_create. |
| RET_OK | The thread is gone and its row is free. |
| RET_INVALID | The handle was not usable. |
| RET_FAIL | ThreadX refused the terminate or the delete. |
Definition at line 473 of file ra8_esp_hosted_rtos.c.
References k_ra8_esp_hosted_max_threads, priv_ra8_esp_hosted_rtos_slot_index(), RA8_INTERNAL, RET_FAIL, RET_INVALID, RET_OK, s_rtos, TX_SUCCESS, tx_thread_delete, and tx_thread_terminate.
Referenced by priv_ra8_esp_hosted_rtos_bind(), and priv_ra8_esp_hosted_rtos_deinit().
|
static |
Start a thread from the fixed thread table.
Copies the name into port-owned storage, claims a table row, and starts the thread on its pre-reserved stack. A stack request larger than one reserved region is refused rather than silently shrunk.
| [in] | tname | Diagnostic name; may be null. |
| [in] | tprio | ThreadX priority (0 is highest). |
| [in] | tstack_size | Requested stack size in bytes. |
| [in] | start_routine | Thread body. |
| [in] | sr_arg | Argument handed to the body. |
| nullptr | The substrate is down, an argument is out of contract, or the thread table is full. |
| non-null | A handle usable with _h_thread_cancel. |
Definition at line 416 of file ra8_esp_hosted_rtos.c.
References ra8_esp_hosted_thread_slot_t::arg, ra8_esp_hosted_thread_slot_t::cb, ra8_esp_hosted_thread_slot_t::entry, internal_copy_name(), internal_thread_entry(), k_ra8_esp_hosted_max_threads, k_ra8_esp_hosted_thread_stack_bytes, ra8_esp_hosted_thread_slot_t::name, priv_ra8_esp_hosted_rtos_slot_take(), RA8_INTERNAL, ra8_log_error, s_rtos, s_tag, s_thread_stacks, TX_AUTO_START, TX_MINIMUM_STACK, TX_NO_TIME_SLICE, TX_SUCCESS, and tx_thread_create.
Referenced by priv_ra8_esp_hosted_rtos_bind().
|
static |
Give up the remainder of the current time slice.
Maps straight onto tx_thread_relinquish; the vendored SPI half-duplex driver uses it to let a peer thread make progress.
Definition at line 506 of file ra8_esp_hosted_rtos.c.
References RA8_INTERNAL, and s_rtos.
Referenced by priv_ra8_esp_hosted_rtos_bind().
|
static |
Create and start a software timer.
H_TIMER_TYPE_ONESHOT becomes a ThreadX timer with a zero reschedule count, so the kernel stops it after one expiry; H_TIMER_TYPE_PERIODIC reschedules at the same interval, so the port never has to re-arm it by hand from the expiry context.
| [in] | name | Diagnostic name; may be null. |
| [in] | duration_ms | Interval in milliseconds; must be positive. |
| [in] | type | H_TIMER_TYPE_ONESHOT or H_TIMER_TYPE_PERIODIC. |
| [in] | timeout_handler | Callback run on each expiry. |
| [in] | arg | Argument handed to the callback. |
| nullptr | An argument was out of contract or the timer table is full. |
| non-null | A handle usable with _h_timer_stop. |
Definition at line 648 of file ra8_esp_hosted_rtos.c.
References ra8_esp_hosted_timer_slot_t::arg, ra8_esp_hosted_timer_slot_t::cb, ra8_esp_hosted_timer_slot_t::cb_fn, H_TIMER_TYPE_ONESHOT, H_TIMER_TYPE_PERIODIC, internal_copy_name(), internal_timer_expiry(), k_ra8_esp_hosted_max_timers, ra8_esp_hosted_timer_slot_t::name, priv_ra8_esp_hosted_rtos_ms_to_ticks(), priv_ra8_esp_hosted_rtos_slot_take(), RA8_INTERNAL, ra8_log_error, s_rtos, s_tag, and TX_SUCCESS.
Referenced by priv_ra8_esp_hosted_rtos_bind().
|
static |
Stop a timer and free its table row.
Deactivates before deleting, which is what ThreadX wants of a running timer, and frees the row last.
| [in] | timer_handle | Handle from _h_timer_start. |
| RET_OK | The timer is stopped, deleted and its row is free. |
| RET_INVALID | The handle was not usable. |
| RET_FAIL | ThreadX refused the deactivate or the delete. |
Definition at line 702 of file ra8_esp_hosted_rtos.c.
References k_ra8_esp_hosted_max_timers, priv_ra8_esp_hosted_rtos_slot_index(), RA8_INTERNAL, RET_FAIL, RET_INVALID, RET_OK, s_rtos, and TX_SUCCESS.
Referenced by priv_ra8_esp_hosted_rtos_bind(), and priv_ra8_esp_hosted_rtos_deinit().
|
static |
Delay for a number of microseconds, honestly.
There is no microsecond timer on this part – ra8_time.h has a millisecond tick and nothing finer – so this splits the request: the whole milliseconds are slept on the RTOS, and only the sub-millisecond remainder is spun out on a bounded cycle-count loop sized from the cached core rate. Nothing is rounded to zero and nothing is faked. Accuracy on the spun part is roughly a factor of two, because cache state, branch prediction and any interrupt taken mid-spin all move it; the slept part is accurate to the kernel tick, so plus or minus one millisecond.
| [in] | useconds | Microseconds to delay. |
| 0 | useconds was zero; nothing was done. |
| useconds | The split delay was executed. |
Definition at line 577 of file ra8_esp_hosted_rtos.c.
References internal_h_msleep(), internal_spin_us(), k_ra8_esp_hosted_us_per_ms, and RA8_INTERNAL.
Referenced by priv_ra8_esp_hosted_rtos_bind().
|
static |
Burn a bounded number of core cycles standing in for a short delay.
The loop counter is volatile so the compiler cannot delete it. The loop itself runs at most k_ra8_esp_hosted_spin_iters_max passes and exits early once the requested, already-clamped iteration count is reached.
| [in] | usec | Microseconds to approximate. |
Definition at line 348 of file ra8_esp_hosted_rtos.c.
References internal_spin_us(), k_ra8_esp_hosted_spin_iters_max, priv_ra8_esp_hosted_rtos_us_spin_iters(), and s_rtos.
Referenced by internal_h_usleep(), and internal_spin_us().
|
static |
ThreadX entry shim that calls the core-supplied thread body.
ThreadX hands a ULONG to a thread; the vendored core wants a void const*. The row index is passed instead of a pointer so a stale entry cannot dereference freed storage.
| [in] | index | Thread table row, passed as the ThreadX entry input. |
Definition at line 299 of file ra8_esp_hosted_rtos.c.
References k_ra8_esp_hosted_max_threads, RA8_INTERNAL, and s_rtos.
|
static |
ThreadX expiry shim that calls the core-supplied timer callback.
Same indirection as the thread entry shim, and for the same reason: ThreadX carries a ULONG, the core wants a void*.
| [in] | index | Timer table row, passed as the ThreadX expiry input. |
Definition at line 322 of file ra8_esp_hosted_rtos.c.
References k_ra8_esp_hosted_max_timers, RA8_INTERNAL, and s_rtos.
| ra8_err_t priv_ra8_esp_hosted_rtos_bind | ( | hosted_osi_funcs_t * | out | ) |
Populate the thread, sleep, timer and clock slots of the vtable.
Writes the ten rows this translation unit implements. It does not call the sibling binders: each unit binds only the rows whose implementations it can see, so a row can never be assigned from a unit that cannot name the function behind it. priv_ra8_esp_hosted_osi_bind_all calls all three. Every slot outside this group – memory, queue, mutex, semaphore, GPIO, bus, logging, transport – is left exactly as the caller had it.
| [out] | out | Vtable to populate. Must be non-null. |
| k_ra8_ok | The ten thread, sleep, timer and clock slots are set. |
| k_ra8_err_null_ptr | out was null. |
Definition at line 814 of file ra8_esp_hosted_rtos.c.
References internal_h_blocking_delay(), internal_h_get_time_ms(), internal_h_msleep(), internal_h_sleep(), internal_h_thread_cancel(), internal_h_thread_create(), internal_h_thread_yield(), internal_h_timer_start(), internal_h_timer_stop(), internal_h_usleep(), k_ra8_ok, RA8_CHECK_NULL_PTR, and s_tag.
Referenced by priv_ra8_esp_hosted_osi_bind_all().
|
nodiscard |
Tear the RTOS substrate down, deleting every outstanding object.
Walks each object table and deletes whatever is still in use – timers are deactivated then deleted, threads terminated then deleted, queues, mutexes and semaphores deleted – then deletes both byte pools and clears the module state. Objects the vendored core still holds handles to are deleted regardless, so the core must be stopped first.
| k_ra8_ok | Everything was released. |
| k_ra8_err_not_initialized | The substrate was not up. |
| k_ra8_err_rtos_error | ThreadX refused to delete an object or a pool. |
Definition at line 787 of file ra8_esp_hosted_rtos.c.
References internal_h_thread_cancel(), internal_h_timer_stop(), k_ra8_err_not_initialized, k_ra8_err_rtos_error, k_ra8_esp_hosted_max_threads, k_ra8_esp_hosted_max_timers, k_ra8_ok, memset(), priv_ra8_esp_hosted_rtos_pool_deinit(), priv_ra8_esp_hosted_rtos_sync_deinit(), ra8_log_error, RET_OK, s_rtos, and s_tag.
Referenced by internal_unwind().
|
nodiscard |
Bring the RTOS substrate up: byte pools and empty object tables.
Creates the two TX_BYTE_POOL instances – the transport buffer pool sized by k_ra8_esp_hosted_pool_bytes and the queue-storage pool sized by k_ra8_esp_hosted_queue_pool_bytes – over static arrays, clears every object table and caches the CPU rate used to size the sub-millisecond spin in _h_usleep. This is the only allocation the RTOS slice ever performs and it happens exactly here, during initialisation.
A second call is an error, not a no-op: a silent success would hand the caller pools whose contents the first caller still owns, and would hide a double bring-up that is always a bug in the calling sequence.
| k_ra8_ok | The substrate is ready; the vtable may be bound. |
| k_ra8_err_invalid_state | The substrate was already initialised. |
| k_ra8_err_rtos_error | ThreadX refused to create a byte pool. |
Definition at line 767 of file ra8_esp_hosted_rtos.c.
References k_ra8_clock_id_cpuclk0, k_ra8_err_invalid_state, k_ra8_esp_hosted_default_cpu_hz, k_ra8_ok, memset(), priv_ra8_esp_hosted_rtos_pool_init(), priv_ra8_esp_hosted_rtos_sync_init(), ra8_cgc_get_clock_hz(), ra8_log_error, ra8_log_warn, RA8_RETURN_ON_ERROR, s_rtos, s_tag, and tx_time_get.
Referenced by internal_bring_up().
|
nodiscard |
Report whether the RTOS substrate is currently initialised.
Reads the single module-state flag so callers can decide whether a teardown is needed without provoking an error return, and so host tests can assert the state machine without reaching into the module.
| true | priv_ra8_esp_hosted_rtos_init completed and no teardown has run. |
| false | The substrate has never been up, failed, or was torn down. |
Definition at line 762 of file ra8_esp_hosted_rtos.c.
References s_rtos.
|
nodiscard |
Convert an esp-hosted millisecond timeout to a ThreadX wait option.
The vendored core expresses every timeout in milliseconds through an int parameter, and ThreadX takes a tick count. Two values are special: zero means "do not block" and HOSTED_BLOCK_MAX (all ones) means "block until satisfied". HOSTED_BLOCK_MAX reaches the vtable as -1 after its conversion to int, so the rule this function implements is "any negative value blocks forever" – deliberately wider than "exactly -1", so a sign-extension bug elsewhere can never turn an intended block into a zero-tick busy loop. The kernel runs at 1 kHz (TX_TIMER_TICKS_PER_SECOND is 1000), so the positive case is the identity; it is still spelled out here rather than inlined at 30 call sites so that changing the tick rate is a one-line change and so the mapping is directly testable.
| [in] | timeout_ms | Timeout in milliseconds: 0 = do not block, negative = block forever, positive = that many milliseconds. |
| 0 | timeout_ms was zero: TX_NO_WAIT. |
| 0xFFFFFFFF | timeout_ms was negative: TX_WAIT_FOREVER. |
| 1..0x7FFFFFFF | The millisecond count, unchanged. |
Definition at line 364 of file ra8_esp_hosted_rtos.c.
References k_ra8_esp_hosted_ms_per_tick, and TX_WAIT_FOREVER.
Referenced by internal_h_dequeue_item(), internal_h_get_semaphore(), internal_h_lock_mutex(), internal_h_queue_item(), and internal_h_timer_start().
|
nodiscard |
Resolve an opaque handle to its row index in a fixed table.
Every handle the port hands the vendored core is the address of a table row. Rather than trusting that address, this scans the table for pointer identity and checks the occupancy flag, so a foreign pointer or a handle retained past its destroy is rejected instead of followed. The tables hold at most eight rows, so the scan is cheaper than any bookkeeping that would replace it.
| [in] | handle | Opaque handle the core is holding. |
| [in] | base | Address of the table's first row. |
| [in] | stride | Bytes between consecutive rows. |
| [in] | count | Number of rows in the table. |
| [in] | used | Occupancy flags for the same table. |
| count | The handle is null, foreign, or names a freed row. |
| 0..count-1 | The live row index. |
Definition at line 230 of file ra8_esp_hosted_rtos.c.
Referenced by 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_thread_cancel(), internal_h_timer_stop(), and internal_h_unlock_mutex().
|
nodiscard |
Claim the first free row of an occupancy bitmap.
The one place a table row is taken, shared by every object kind so none of them can grow its table by accident. Returning count rather than a sentinel index keeps the caller's bound check and the failure check the same comparison.
| [in,out] | used | Occupancy flags; must cover count entries. |
| [in] | count | Number of rows in the table. |
| count | Every row was occupied, or used was null. |
| 0..count-1 | The claimed row, now marked in use. |
Definition at line 216 of file ra8_esp_hosted_rtos.c.
Referenced by internal_h_create_mutex(), internal_h_create_semaphore(), internal_h_thread_create(), and internal_h_timer_start().
|
nodiscard |
Size the busy-wait loop that stands in for a microsecond delay.
There is no microsecond timer on this target: ra8_time.h offers a millisecond tick and a millisecond busy delay, and nothing finer. Rather than fake a microsecond sleep or round every sub-millisecond request to zero, _h_usleep spins, and this function decides for how long. The estimate is cpu_hz / 1e6 cycles per microsecond divided by k_ra8_esp_hosted_spin_cycles_per_iter, the measured cost of one iteration of the volatile-counter loop on the Cortex-M85.
The result is clamped to k_ra8_esp_hosted_spin_iters_max so the loop is statically bounded (NASA Power of 10 Rule 2) whatever the caller asks for. Accuracy is roughly a factor of two: cache state, the branch predictor and any interrupt taken mid-spin all move the real duration, and none of them is modelled. That is stated rather than hidden – a caller needing better than that needs a hardware timer, not a better guess.
| [in] | cpu_hz | Core clock in hertz; zero means "rate unknown". |
| [in] | usec | Microseconds to spin for. |
| 0 | cpu_hz or usec was zero: do not spin at all. |
| 1..k_ra8_esp_hosted_spin_iters_max | The clamped iteration count. |
Definition at line 375 of file ra8_esp_hosted_rtos.c.
References k_ra8_esp_hosted_hz_per_mhz, k_ra8_esp_hosted_spin_cycles_per_iter, and k_ra8_esp_hosted_spin_iters_max.
Referenced by internal_spin_us().
|
static |
Singleton state of the thread, timer and clock half.
Zero-initialised at link time; brought up by priv_ra8_esp_hosted_rtos_init.
Definition at line 198 of file ra8_esp_hosted_rtos.c.
Referenced by internal_h_get_time_ms(), internal_h_msleep(), internal_h_thread_cancel(), internal_h_thread_create(), internal_h_thread_yield(), internal_h_timer_start(), internal_h_timer_stop(), internal_spin_us(), internal_thread_entry(), internal_timer_expiry(), priv_ra8_esp_hosted_rtos_deinit(), priv_ra8_esp_hosted_rtos_init(), and priv_ra8_esp_hosted_rtos_is_ready().
|
static |
Log tag for the synchronisation half of the port.
Shared by every diagnostic this translation unit emits.
Definition at line 49 of file ra8_esp_hosted_rtos.c.
|
static |
Fixed stack storage, one region per thread table row.
Sized by k_ra8_esp_hosted_thread_stack_bytes, which covers the deepest stack the vendored core asks for.
Definition at line 210 of file ra8_esp_hosted_rtos.c.
Referenced by internal_h_thread_create().