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

RA8 <-> Eclipse ThreadX glue: SysTick kernel-tick retuning. More...

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

Go to the source code of this file.

Enumerations

enum  ra8_threadx_tick_t : uint32_t { k_ra8_threadx_tick_hz = 1000UL }
 ThreadX kernel tick rate used to derive the SysTick reload. More...
enum  ra8_systick_reload_limit_t : uint32_t { k_ra8_systick_reload_max = 0x00FFFFFFUL }
 Architectural range limit of the Cortex-M SysTick reload register. More...

Functions

ra8_err_t ra8_threadx_systick_reload_for (uint32_t cpuclk_hz, uint32_t tick_hz, uint32_t *out_reload)
 Compute the SysTick reload for a given core clock + tick rate.
ra8_err_t ra8_threadx_systick_retune (void)
 Reprogram SysTick.LOAD from the live CPUCLK0 rate.

Detailed Description

RA8 <-> Eclipse ThreadX glue: SysTick kernel-tick retuning.

The project-tuned tx_initialize_low_level.S programs SysTick from a compile-time clock assumption (RA8_BOOT_CLOCK_HZ, 1 GHz – the post-CGC CPUCLK0 target). That is correct only if the app raised CPUCLK0 to exactly that rate before tx_kernel_enter(). An app that enters the kernel on a different clock – the boot-default MOCO (~8 MHz), or any other CGC target – would run the ThreadX kernel tick at the wrong rate: a nominal 1 ms tick scaled by the ratio of the compile-time assumption to the live clock (~119x too slow on MOCO).

ra8_threadx_systick_retune closes that gap. Called from tx_application_define – which ThreadX runs AFTER _tx_initialize_low_level but BEFORE the first scheduling decision – it re-derives SysTick.LOAD from the live CPUCLK0 rate reported by ra8_cgc_get_clock_hz, so the kernel tick is accurate regardless of which clock the app brought up. If the live clock is so high that the per-tick reload cannot fit the 24-bit SYST_RVR register, the function returns an error rather than silently truncating the reload – the caller can then halt instead of drifting.

ra8_threadx_systick_reload_for is the pure arithmetic core, split out so the range/validity logic is host-unit-testable without touching the Cortex-M System Control Space.

Note
All functions here run in a single-threaded init context (tx_application_define, IRQs masked). None are thread-safe.
Since
0.1.0

Definition in file ra8_threadx.h.

Enumeration Type Documentation

◆ ra8_systick_reload_limit_t

enum ra8_systick_reload_limit_t : uint32_t

Architectural range limit of the Cortex-M SysTick reload register.

SYST_RVR (0xE000E014) has a 24-bit RELOAD field (bits [23:0]); the top byte reads as zero. A reload larger than this cannot be represented, so ra8_threadx_systick_reload_for rejects it instead of truncating.

Invariant
Equal to (1 << 24) - 1.
Enumerator
k_ra8_systick_reload_max 

Max SYST_RVR reload (24-bit).

Definition at line 75 of file ra8_threadx.h.

◆ ra8_threadx_tick_t

enum ra8_threadx_tick_t : uint32_t

ThreadX kernel tick rate used to derive the SysTick reload.

Mirrors TX_TIMER_TICKS_PER_SECOND in port/threadx/inc/tx_user.h. The two MUST agree: tx_user.h declares the rate ThreadX assumes for tx_thread_sleep / timer math, and this value is what ra8_threadx_systick_retune programs SysTick to fire at.

Invariant
Equal to TX_TIMER_TICKS_PER_SECOND.
See also
ra8_threadx_systick_retune
Enumerator
k_ra8_threadx_tick_hz 

1 kHz -> 1 ms kernel tick.

Definition at line 60 of file ra8_threadx.h.

Function Documentation

◆ ra8_threadx_systick_reload_for()

ra8_err_t ra8_threadx_systick_reload_for ( uint32_t cpuclk_hz,
uint32_t tick_hz,
uint32_t * out_reload )
nodiscard

Compute the SysTick reload for a given core clock + tick rate.

Derives the SYST_RVR reload value as cpuclk_hz / tick_hz - 1, the count that makes SysTick underflow once per tick period. Validates that the inputs are non-zero, that the clock is fast enough for at least one tick period (cpuclk_hz >= tick_hz), and that the resulting reload fits the 24-bit SYST_RVR field. Pure arithmetic – touches no hardware – so it is exercised directly by the host MC/DC unit tests.

Parameters
[in]cpuclk_hzLive core (CPUCLK0) frequency in Hz. Must be > 0.
[in]tick_hzKernel tick rate in Hz (see k_ra8_threadx_tick_hz). Must be > 0.
[out]out_reloadOn success, the SYST_RVR reload value to program.
Returns
ra8_err_t error code.
Return values
k_ra8_okReload computed and written to out_reload.
k_ra8_err_null_ptrout_reload is NULL.
k_ra8_err_invalid_argcpuclk_hz or tick_hz is 0, or the clock is slower than one tick period.
k_ra8_err_out_of_rangeReload would exceed the 24-bit SYST_RVR range (cpuclk_hz far too high for tick_hz).
Precondition
out_reload is a valid, writable uint32_t.
Caller supplies the live clock, not a compile-time assumption.
Postcondition
On k_ra8_ok, *out_reload <= k_ra8_systick_reload_max.
On any error, out_reload is left unmodified.
Note
Thread safety: pure function, trivially thread-safe.
Example:
uint32_t reload = 0U;
// 1 GHz core, 1 kHz tick -> 999999.
(void)ra8_threadx_systick_reload_for(1000000000U, 1000U, &reload);
ra8_err_t ra8_threadx_systick_reload_for(uint32_t cpuclk_hz, uint32_t tick_hz, uint32_t *out_reload)
Compute the SysTick reload for a given core clock + tick rate.
See also
ra8_threadx_systick_retune
Since
0.1.0

Definition at line 34 of file tx_systick_retune.c.

References k_ra8_err_invalid_arg, k_ra8_err_out_of_range, k_ra8_ok, k_ra8_systick_reload_max, RA8_CHECK_NULL_PTR, ra8_log_error, and s_tag.

Referenced by ra8_threadx_systick_retune(), and tx_application_define().

◆ ra8_threadx_systick_retune()

ra8_err_t ra8_threadx_systick_retune ( void )
nodiscard

Reprogram SysTick.LOAD from the live CPUCLK0 rate.

Queries the live CPUCLK0 frequency via ra8_cgc_get_clock_hz, derives the reload with ra8_threadx_systick_reload_for for the ThreadX tick rate (k_ra8_threadx_tick_hz), then writes SYST_RVR and clears SYST_CVR so the new period takes effect on the next reload. The SysTick enable / clock-source / interrupt bits programmed by _tx_initialize_low_level.S are left untouched.

Call this from tx_application_define (which ThreadX invokes after _tx_initialize_low_level but before the first scheduling decision) so that whatever clock the app raised via ra8_cgc_init() – or did not – the kernel tick is accurate. Calling it earlier (from main before tx_kernel_enter) has no effect: _tx_initialize_low_level reprograms SYST_RVR afterwards and would overwrite it.

Returns
ra8_err_t error code.
Return values
k_ra8_okSysTick reprogrammed for the live clock.
k_ra8_err_invalid_argCPUCLK0 query returned a nonsensical rate (0, or too slow for one tick period).
k_ra8_err_out_of_rangeLive clock too high for a 24-bit reload.
Precondition
_tx_initialize_low_level has already armed SysTick (i.e. this runs from tx_application_define or later).
The CGC published-clock table reflects the live clock (i.e. ra8_cgc_init() has run if the app raises the clock).
Postcondition
On k_ra8_ok, SYST_RVR == CPUCLK0 / k_ra8_threadx_tick_hz - 1.
On k_ra8_ok, SYST_CVR == 0 (counter restarts at the new reload).
Note
Thread safety: not thread-safe; single-threaded init context only.
On the host unit-test build (RA8_OFF_TARGET) the SYST_RVR / SYST_CVR writes are skipped – the System Control Space is not mapped – but the clock query + reload validation still run.
Example:
void tx_application_define(void* unused) {
(void)unused;
if (ra8_threadx_systick_retune() != k_ra8_ok) { for (;;) { } }
// ... tx_thread_create(...) ...
}
void tx_application_define(void *first_unused_memory)
ThreadX system-define hook: build worker thread + byte pool.
Definition main.c:942
@ k_ra8_ok
Success – operation completed with all postconditions satisfied.
Definition ra8_err.h:119
ra8_err_t ra8_threadx_systick_retune(void)
Reprogram SysTick.LOAD from the live CPUCLK0 rate.
See also
ra8_threadx_systick_reload_for
ra8_cgc_get_clock_hz
Since
0.1.0

Definition at line 64 of file tx_systick_retune.c.

References k_ra8_clock_id_cpuclk0, k_ra8_ok, k_ra8_threadx_tick_hz, ra8_cgc_get_clock_hz(), ra8_log_info_val, RA8_RETURN_ON_ERROR, ra8_systick_set_reload(), ra8_threadx_systick_reload_for(), and s_tag.

Referenced by tx_application_define().